题意:一共n个数,去掉其中一个,问剩余n-1个数gcd的最大值
解题思路:rmq或者求前缀和后缀
RMQ:
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <map> #include <cmath> #include <set> #include <stack> #include <queue> #include <vector> #include <bitset> #include <functional> using namespace std; #define LL long long const int INF=0x3f3f3f3f; int a[100006],n; int dp[100006][20]; int gcd(int x,int y) { if(x>y) swap(x,y); while(y%x) { int k=y%x; y=x; x=k; } return x; } void init() { for(int i=1;i<=n;i++) dp[i][0]=a[i]; for(int i=1;(1<<i)<=n;i++) for(int j=1;j+(1<<i)-1<=n;j++) dp[j][i]=gcd(dp[j][i-1],dp[j+(1<<(i-1))][i-1]); } int query(int l,int r) { int k=0; while(1<<(k+1)<=r-l+1) k++; return gcd(dp[l][k],dp[r-(1<<k)+1][k]); } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); init(); int ma=-1; for(int i=2;i<n;i++) { int k=query(1,i-1),kk=query(i+1,n); ma=max(ma,gcd(k,kk)); } ma=max(ma,query(2,n)); ma=max(ma,query(1,n-1)); printf("%d\n",ma); } return 0; }
前缀+后缀
#include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> #include <cmath> #include <map> #include <cmath> #include <set> #include <stack> #include <queue> #include <vector> #include <bitset> #include <functional> using namespace std; #define LL long long const int INF=0x3f3f3f3f; int a[100005],x[100005],y[100005]; int gcd(int a,int b) { return b==0?a:gcd(b,a%b); } int main() { int t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); for(int i=0; i<n; i++) scanf("%d",&a[i]); x[0]=a[0]; for(int i=1; i<n; i++) x[i]=gcd(x[i-1],a[i]); y[n-1]=a[n-1]; for(int i=n-2; i>=0; i--) y[i]=gcd(y[i+1],a[i]); int ans=max(y[1],x[n-2]); for(int i=1; i<n-1; i++) ans=max(ans,gcd(x[i-1],y[i+1])); printf("%d\n",ans); } return 0; }