不知谁说过一句名句,我们要学会复杂度分析
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define rep(i,a,b) for(int i=a;i<=b;++i) 4 #define fd(i,a,b) for(int i=a;i>=b;--i) 5 const int maxn=100010; 6 typedef long long ll; 7 inline ll gi() { 8 ll x=0; char o; bool f=true; for(;!isdigit(o=getchar());) if(o=='-')f=false; 9 for(;isdigit(o);o=getchar()) x=(x<<1)+(x<<3)+(o&15); return f?x:~x+1; 10 } 11 ll ans,a[maxn],pre[maxn<<2][20]; 12 int n; 13 ll gcd(ll x,ll y){return x?gcd(y%x,x):y;} 14 ll gt(int s,int t) { 15 ll ret=a[s]; 16 fd(i,18,0) if(s+(1<<i)-1<=t) 17 ret=gcd(ret,pre[s][i]),s=s+(1<<i); 18 return ret; 19 } 20 int Find(int l,int r,int s,ll v) { 21 int ret=l; 22 while( l<=r) { 23 int mid=l+r>>1; 24 if(gt(s,mid)>=v) ret=mid,l=mid+1; 25 else r=mid-1; 26 } 27 return ret; 28 } 29 int main() { 30 #ifndef ONLINE_JUDGE 31 freopen("3.in","r",stdin); 32 #endif 33 scanf("%d",&n); rep(i,1,n) a[i]=pre[i][0]=gi(); 34 rep(k,1,18) rep(i,1,n) 35 pre[i][k]=gcd(pre[i+(1<<k-1)][k-1],pre[i][k-1]); 37 rep(i,1,n) { 38 int L=i; 39 while(L<=n) { 40 ll val=gt(i,L); int ed=Find(i,n,i,val); 41 ans=max(ans,1LL*(ed-i+1)*val); L=ed+1; 43 } 44 } 45 printf("%lld\n",ans); 46 return 0; 47 }