#分治#洛谷 5502 [JSOI2015]最大公約數
阿新 • • 發佈:2020-08-09
分析
又是一道思維題,考慮用分治,選取左邊或右邊的基準儘量擴充套件長度,時間複雜度\(O(nlog_2n)\)
程式碼
#include <cstdio> #include <cctype> #define rr register typedef long long lll; lll n,a[1000011]; inline lll iut(){ rr lll ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline lll max(lll a,lll b){return a>b?a:b;} inline lll gcd(lll a,lll b){return b?gcd(b,a%b):a;} inline lll dfs(int l,int r){ if (l==r) return a[l]; rr int mid=(l+r)>>1,L=mid,R=mid+1; rr lll now=gcd(a[mid],a[mid+1]),ans=now<<1; ans=max(ans,max(dfs(l,mid),dfs(mid+1,r))); while (L>=l&&R<r){ now=gcd(now,a[++R]); for (;L>=l&&!(a[L]%now);--L); ++L; for (;R<=r&&!(a[R]%now);++R); --R; ans=max(ans,now*(R-L+1)); } now=gcd(a[mid],a[mid+1]),L=mid,R=mid+1; while (L>l&&R<=r){ now=gcd(now,a[--L]); for (;L>=l&&!(a[L]%now);--L); ++L; for (;R<=r&&!(a[R]%now);++R); --R; ans=max(ans,now*(R-L+1)); } return ans; } signed main(){ n=iut(); for (rr int i=1;i<=n;++i) a[i]=iut(); return !printf("%lld",dfs(1,n)); }