题目链接:传送门
思路:
- 进行预处理的算法模板:
-
for(int i=1;(1<<i)<=n;i++) for(int j=1;j+(1<<i)-1<=n;j++) st[j][i]=gcd(st[j][i-1],st[j+(1<<(i-1))][i-1]);
- 进行查询的算法模板
int check(int i,int mid){
int k=log2(mid-i+1);
return gcd(st[i][k],st[mid-(1<<k)+1][k]);
}
AC代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10;
int a[N],f[N/2][30],_gcd;
int n,ans=-5;
void unit(){
for(int i=1;i<=20;i++){
for(int j=1;j+(1<<i)-1<=n*2;j++){
f[j][i]=__gcd(f[j][i-1],f[j+(1<<(i-1))][i-1]);
}
}
}
int check(int i,int mid){
int op=log2(mid-i+1);
return __gcd(f[i][op],f[mid-(1<<op)+1][op]);
}
void bs(int l,int r,int i){
while(l<r){
int mid=(l+r)/2;
if(check(i,mid)==_gcd) r=mid;
else l=mid+1;
}
l--;
ans=max(ans,l-i+1);
}
void solve(){
cin>>n;
int flag=0;
for(int i=1;i<=n;i++){
cin>>a[i];
a[i+n]=a[i];
if(a[i]!=a[1]){
flag=1;
}
f[i+n][0]=f[i][0]=a[i];
if(i==1) _gcd=a[i];
else _gcd=__gcd(_gcd,a[i]);
}
if(flag==0){
cout<<"0\n";
return ;
}
unit();
for(int i=1;i<=n;i++){
bs(i,i+n-1,i);
}
cout<<ans<<"\n";
return ;
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
cin>>t;
while(t--){
ans=-1;
solve();
}
}