这个CF D是个一眼题。但是我写了1个多小时才写完又花了30多分钟才调完,求个简单做法。
我的代码:
#include<bits/stdc++.h>
using namespace std;
inline long long read(){
long long x=0;
bool f=0;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-') f^=1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<3)+(x<<1)+ch-'0';
ch=getchar();
}
if(f) return -x;
return x;
}
void write(long long x){
static int sta[20];
int top=0;
if(x<0) putchar('-'),x=-x;
do{
sta[top++]=x%10,x/=10;
}while(x);
while(top) putchar(sta[--top]+48);
}
void we(long long x){
write(x);
putchar('\n');
}
void put(string s){
int len=s.length();
for(int i=0;i<len;i++){
putchar(s[i]);
}
}
int t,n,m,a[200010],b[200010],gdd[200010][21],gdd2[200010][21],m1,m2;
int dd[200010][34],dd2[200010][34],ww[200010][34],ww2[200010][34],lg2[1000010];
//int gcd(int id,int l,int r){
// int len=r-l+1;
// if(id) return __gcd(gdd2[l][lg2[len]],gdd2[r-(1<<lg2[len])+1][lg2[len]]);
// else return __gcd(gdd[l][lg2[len]],gdd[r-(1<<lg2[len])+1][lg2[len]]);
//}
int calc(int id,int l,int num){
if(id==0){
for(int i=19;i>=0;i--){
if(l+(1<<i)>n+1) continue;
if(gdd[l][i]%num==0) l+=(1<<i);
}
return l;
}
else{
for(int i=19;i>=0;i--){
if(l+(1<<i)>n+1) continue;
if(gdd2[l][i]%num==0) l+=(1<<i);
}
return l;
}
}
int main(){
t=read();
for(int i=1;i<=18;i++){
for(int j=(1<<i);j<=(1<<(i+1))-1;j++) lg2[j]=i;
}
while(t--){
n=read();
m1=m2=0;
for(int i=1;i<=n;i++) a[i]=read(),m1=__gcd(a[i],m1);
for(int i=1;i<=n;i++) b[i]=read(),m2=__gcd(b[i],m2);
for(int i=1;i<=n;i++){
gdd[i][0]=a[i];
gdd2[i][0]=b[i];
}
for(int i=1;i<=19;i++){
for(int j=1;j<=n+1-(1<<i);j++){
gdd[j][i]=__gcd(gdd[j][i-1],gdd[j+(1<<(i-1))][i-1]);
gdd2[j][i]=__gcd(gdd[j][i-1],gdd[j+(1<<(i-1))][i-1]);
}
}
int cc=0;
for(int i=0;i<=n;i++){
cc=__gcd(cc,a[i]);
int temp=cc,tot=0,wz=n;
if(i==0||a[n]%temp!=0) temp=__gcd(a[n],temp),dd[i][++tot]=n,ww[i][tot]=temp;
while(temp!=m1){
for(int j=19;j>=0;j--){
if(wz-(1<<j)<=i) continue;
if(gdd[wz-(1<<j)+1][j]%temp==0) wz=wz-(1<<j);
}
//--wz;
temp=__gcd(a[wz],temp);
dd[i][++tot]=wz;
ww[i][tot]=temp;
}
dd[i][tot+1]=n+1;
ww[i][tot+1]=cc;
if(tot==0) continue;
reverse(dd[i]+1,dd[i]+tot+1);
reverse(ww[i]+1,ww[i]+tot+1);
}
cc=0;
for(int i=0;i<=n;i++){
cc=__gcd(cc,b[i]);
int temp=cc,tot=0,wz=n;
if(i==0||b[n]%temp!=0) temp=__gcd(b[n],temp),dd2[i][++tot]=n,ww2[i][tot]=temp;
while(temp!=m2){
for(int j=19;j>=0;j--){
if(wz-(1<<j)<=i) continue;
if(gdd2[wz-(1<<j)+1][j]%temp==0) wz=wz-(1<<j);
}
temp=__gcd(b[wz],temp);
dd2[i][++tot]=wz;
ww2[i][tot]=temp;
}
dd2[i][tot+1]=n+1;
ww2[i][tot+1]=cc;
if(tot==0) continue;
reverse(dd2[i]+1,dd2[i]+tot+1);
reverse(ww2[i]+1,ww2[i]+tot+1);
}
int ans=0;
long long ans2=0;
for(int i=1;i<=n;i++){
int l=i,l1=calc(0,i,a[i]),l2=calc(1,i,b[i]),l3=1,l4=1;
int nm1=a[i],nm2=b[i];
while(l<n+1){
//cout<<dd[i-1][l3]<<" "<<ww[i-1][l3]<<" "<<dd2[i-1][l4]<<" "<<ww2[i-1][l4]<<endl;
int mnn=min(min(l1-1,l2-1),min(dd[i-1][l3]-1,dd2[i-1][l4]-1));
int tmp=__gcd(nm1,ww2[i-1][l4])+__gcd(nm2,ww[i-1][l3]);
if(tmp>ans){
ans=tmp;
ans2=mnn-l+1;
}
else if(tmp==ans) ans2+=mnn-l+1;
l=mnn+1;
if(l1==l) nm1=__gcd(a[l1],nm1),l1=calc(0,l1,nm1);
if(l2==l) nm2=__gcd(b[l2],nm2),l2=calc(1,l2,nm2);
if(dd[i-1][l3]==l) ++l3;
if(dd2[i-1][l4]==l) ++l4;
//cout<<i<<" "<<l<<" "<<l1<<" "<<nm1<<" "<<l2<<" "<<nm2<<" "<<l3<<" "<<l4<<" "<<ans<<" "<<ans2<<endl;
}
}
write(ans);
putchar(' ');
write(ans2);
putchar('\n');
for(int i=0;i<=19;i++){
for(int j=1;j<=n+1-(1<<i);j++){
gdd[j][i]=0;
gdd2[j][i]=0;
}
}
for(int i=0;i<=32;i++){
for(int j=0;j<=n;j++){
dd[j][i]=dd2[j][i]=ww[j][i]=ww2[j][i]=0;
}
}
}
return 0;
}