【NOIP 校內模擬】T1 優美的序列(二分+st表+卡常)
阿新 • • 發佈:2018-12-30
我是菜雞 我是蒟蒻 我好菜
ak一定是區間最小的值,且是所有數(包括自己)的最大公約數
我沒看出來 沒救了 noip爆零了 回家養豬了 沒學上了 怎麼辦
gcd有單調性 gcd有單調性 gcd有單調性 gcd有單調性 gcd有單調性 可以二分 可以二分 可以二分 可以二分 要說多少遍才記得到
我沒想到 沒救了 noip爆零了 回家養豬了 沒學上了 怎麼辦
stl少用 stl少用 stl少用 stl少用 要說多少遍
我忘了 沒救了 noip爆零了 回家養豬了 沒學上了 怎麼辦
#include<bits/stdc++.h> #define N 500005 #define re register using namespace std; int n,a[N],gcd[N][21],maxd; vector<int> ans; inline int calc(int a,int b) { re int t; while (b) t=a,a=b,b=t%b; return a; } int LOG[N]; void init() { LOG[0]=-1; for(re int i=1;i<=n;++i) gcd[i][0]=a[i],LOG[i]=LOG[i/2]+1; for(re int j=1;j<=21;++j) { for(re int i=1;i+(1<<j)-1<=n;++i) gcd[i][j]=calc(gcd[i][j-1],gcd[i+(1<<(j-1))][j-1]); } } inline int query(int l,int r) { int k=LOG[r-l+1]; return calc(gcd[l][k],gcd[r-(1<<k)+1][k]); } int main() { ios::sync_with_stdio(false); cin.tie(NULL);cout.tie(NULL); cin>>n; for(re int i=1;i<=n;++i) cin>>a[i]; init(); for(re int i=1;i<=n;++i) //列舉最小的 { re int l=1,r=i,mid; re int ans1=i,ans2=i; while(l<=r) { mid=(l+r)>>1; if(query(mid,i)==a[i]) ans1=mid,r=mid-1; else l=mid+1; } l=i,r=n; while(l<=r) { mid=(l+r)>>1; if(query(i,mid)==a[i]) ans2=mid,l=mid+1; else r=mid-1; } if(ans2-ans1==maxd) ans.push_back(ans1); if(ans2-ans1>maxd) ans.clear(),maxd=ans2-ans1,ans.push_back(ans1); } vector<int>::iterator it=unique(ans.begin(),ans.end()); cout<<it-ans.begin()<<" "<<maxd<<'\n'; for(re vector<int>::iterator i=ans.begin();i!=it;++i) cout<<*i<<' '; }