【noip模擬賽】數字對
阿新 • • 發佈:2018-12-30
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<queue> #define ll long long #define inf 2147483647 using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int bin[20]; int n,top,res; int a[500005],L[500005],q[500005],ans[500005]; int mn[500005][19],g[500005][19]; int gcd(int x,int y) { return y==0?x:gcd(y,x%y); } void pre() { for(int i=1;i<=n;i++) mn[i][0]=g[i][0]=a[i]; for(int j=1;j<=18;j++) for(int i=1;i<=n;i++) { if(i+bin[j]-1<=n) { mn[i][j]=min(mn[i][j-1],mn[i+bin[j-1]][j-1]); g[i][j]=gcd(g[i][j-1],g[i+bin[j-1]][j-1]); } else break; } } bool query(int l,int r) { int t=L[r-l+1],R=r-bin[t]+1; return min(mn[l][t],mn[R][t])==gcd(g[l][t],g[R][t]); } void solve(int x) { for(int i=1;i<=n;i++) if(i+x-1<=n) if(query(i,i+x-1)) ans[++top]=i; } int main() { //freopen("pair.in","r",stdin); //freopen("pair.out","w",stdout); bin[0]=1;for(int i=1;i<20;i++)bin[i]=bin[i-1]<<1; L[0]=-1;for(int i=1;i<=500000;i++)L[i]=L[i>>1]+1; n=read(); for(int i=1;i<=n;i++)a[i]=read(); pre(); int l=1,r=500000; while(l<=r) { int mid=(l+r)>>1; top=0; solve(mid); if(top)res=mid,l=mid+1; else r=mid-1; } top=0; solve(res); printf("%d %d\n",top,res-1); for(int i=1;i<=top;i++) printf("%d ",ans[i]); return 0; }