求刚才CF D的30分钟内就能实现的做法
  • 板块学术版
  • 楼主ricky0916
  • 当前回复5
  • 已保存回复5
  • 发布时间2024/9/15 01:13
  • 上次更新2024/9/15 11:33:21
查看原帖
求刚才CF D的30分钟内就能实现的做法
289230
ricky0916楼主2024/9/15 01:13

这个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;
}
2024/9/15 01:13
加载中...