CodeForces - 1547F Array Stabilization (GCD version)(ST表+二分)
題目鏈接:點(diǎn)擊查看
題目大意:給出一個(gè)長度為 nnn 的數(shù)組 aaa,下標(biāo)從 000 開始,每次操作分為兩個(gè)步驟:
問至少需要操作多少次,才能使得數(shù)組 aaa 的每個(gè)元素都相等
題目分析:
方便起見,下文中的下標(biāo) (i+1)modn(i+1)\mod n(i+1)modn 統(tǒng)一用 i+1i+1i+1 表示
需要分析出:
不難看出當(dāng) kkk 取 nnn 時(shí),所有的數(shù)字都等于 nnn 個(gè)數(shù)的最大公約數(shù),所以操作次數(shù)最多有 nnn 次,最少有 000 次
顯然 kkk 具有單調(diào)性,所以考慮二分 kkk,現(xiàn)在問題是如何快速去求區(qū)間 gcdgcdgcd,這里給出兩種方法,第一種就是最簡單的線段樹,但是如果嚴(yán)格來計(jì)算復(fù)雜度的話,線段樹拆分區(qū)間一層 logloglog,gcdgcdgcd 一層 logloglog,所以總的時(shí)間復(fù)雜度是 nlog3nnlog^3nnlog3n 的,但好像是可以通過本題的?
又因?yàn)槭庆o態(tài)查詢,所以不妨直接打個(gè) STSTST 表,這樣可以優(yōu)化掉一層 logloglog,復(fù)雜度是 nlog2nnlog^2nnlog2n 的,但 gcdgcdgcd 的那層 logloglog 好像很小,所以近似于 nlognnlognnlogn 的
循環(huán)取模的話,只需要將數(shù)組復(fù)制一遍就可以了
代碼:
// Problem: F. Array Stabilization (GCD version) // Contest: Codeforces - Codeforces Round #731 (Div. 3) // URL: https://codeforces.com/contest/1547/problem/F // Memory Limit: 512 MB // Time Limit: 4000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #define lowbit(x) x&-x using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100; int a[N],st[N][20],n; void ST_build() {for(int i=1;i<=n<<1;i++)st[i][0]=a[i];for(int i=1;i<=20;i++)for(int j=1;j+(1<<i)-1<=n<<1;j++)st[j][i]=__gcd(st[j][i-1],st[j+(1<<(i-1))][i-1]); } int ST_query(int l,int r) {int k=log2(r-l+1);return __gcd(st[l][k],st[r-(1<<k)+1][k]); } bool check(int len) {int mark=ST_query(1,1+len);for(int i=2;i<=n;i++) {if(mark!=ST_query(i,i+len)) {return false;}}return true; } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--) {read(n);for(int i=1;i<=n;i++) {read(a[i]);a[i+n]=a[i];}ST_build();int l=0,r=n,ans=-1;while(l<=r) {int mid=(l+r)>>1;if(check(mid)) {r=mid-1;ans=mid;} else {l=mid+1;}}cout<<ans<<endl;}return 0; }總結(jié)
以上是生活随笔為你收集整理的CodeForces - 1547F Array Stabilization (GCD version)(ST表+二分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CodeForces - 1539F S
- 下一篇: CodeForces - 1547G H