cunzai_zsy0531

关注我

CF1398G Running Competition 题解

\(c_i=0/1\) 表示 \(i\) 有没有在 \(a\) 中出现,那么这个就是他自己和自己的差卷积,卷出来之后不是 \(0\) 的位置就都可以,每个可以的位置更新一下自己的倍数就行(或者使用狄利克雷前缀和,不过暴力做复杂度也过得去)。

差卷积就翻一下序列然后 FFT 就行了。

点击查看代码
const int N=8e5+13,M=1e6+13;
const int G=114514,Gi=qpow(G,mod-2);
int n,m,in[N],a[N],b[N],c[M],r[N];
inline void fft(int *f,int limit,int type){
	for(int i=0;i<limit;++i)
		if(i<r[i]) swap(f[i],f[r[i]]);
	for(int mid=1;mid<limit;mid<<=1){
		int Wn=qpow(type==1?G:Gi,(mod-1)/(mid<<1));
		for(int j=0;j<limit;j+=(mid<<1)){
			int w=1;
			for(int k=0;k<mid;++k,w=1ll*w*Wn%mod){
				int x=f[j+k],y=1ll*w*f[j+k+mid]%mod;
				f[j+k]=(x+y)%mod;f[j+k+mid]=(x-y+mod)%mod;
			}
		}
	}
	if(type==1) return;
	int inv=qpow(limit,mod-2);
	for(int i=0;i<limit;++i) f[i]=(ll)f[i]*inv%mod;
}
inline void mul(int *a,int *b){
	int limit=1,l=0;
	while(limit<=(m<<1)) limit<<=1,++l;
	for(int i=0;i<limit;++i) r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
	fft(a,limit,1),fft(b,limit,1);
	for(int i=0;i<limit;++i) a[i]=(ll)a[i]*b[i]%mod;
	fft(a,limit,-1);
}
int main(){
	read(n),read(m);int ll;read(ll);
	for(int i=1;i<=n+1;++i){
		int x;read(x);
		a[x]=b[m-x]=1;
	}
	mul(a,b);int lim=1e6;
	for(int i=m+1;i<=(m<<1);++i){
		if(!a[i]) continue;
		int l=(i-m+ll)<<1;
		for(int j=l;j<=lim;j+=l) c[j]=max(c[j],l);
	}
	int q;read(q);
	while(q--){
		int x;read(x);
		if(!c[x]) print(-1),print(' ');
		else print(c[x]),print(' ');
	}
	return 0;
}
posted @ 2022-05-28 15:04  cunzai_zsy0531  阅读(42)  评论(0编辑  收藏  举报