UVA12879 Golf Bot
或许我应该把这道题放到I.BZOJ3513: [MUTC2013]idiots前面的QaQ。
这题完全就是那题的子问题,直接暴力FFT一下即可。连特殊情况都不需要考虑。
感觉这题被恶评了,应该是紫-,不可能到黑。
代码:
#include<bits/stdc++.h>
using namespace std;
const int lg=19,lim=(1<<lg);
const double pi=acos(-1);
int n,m,cnt[lim+5],res,rev[lim+5];
struct cp{
double x,y;
cp(double u=0,double v=0){x=u,y=v;}
friend cp operator +(const cp &u,const cp &v){return cp(u.x+v.x,u.y+v.y);}
friend cp operator -(const cp &u,const cp &v){return cp(u.x-v.x,u.y-v.y);}
friend cp operator *(const cp &u,const cp &v){return cp(u.x*v.x-u.y*v.y,u.x*v.y+u.y*v.x);}
}f[lim+5];
void FFT(cp *a,int tp){
for(int i=0;i<lim;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int md=1;md<lim;md<<=1){
cp rt=cp(cos(pi/md),tp*sin(pi/md));
for(int stp=md<<1,pos=0;pos<lim;pos+=stp){
cp w=cp(1,0);
for(int i=0;i<md;i++,w=w*rt){
cp x=a[pos+i],y=w*a[pos+md+i];
a[pos+i]=x+y;
a[pos+md+i]=x-y;
}
}
}
}
int main(){
for(int i=0;i<lim;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lg-1));
while(scanf("%d",&n)!=EOF){
for(int i=0;i<lim;i++)f[i]=cp(0,0),cnt[i]=0;
f[0].x=1;
res=0;
for(int i=0,x;i<n;i++)scanf("%d",&x),f[x].x+=1;
FFT(f,1);
for(int i=0;i<lim;i++)f[i]=f[i]*f[i];
FFT(f,-1);
for(int i=0;i<lim;i++)cnt[i]=(int)(f[i].x/lim+0.5);
// for(int i=1;i<=10;i++)printf("%d ",cnt[i]);
scanf("%d",&m);
for(int i=0,x;i<m;i++)scanf("%d",&x),res+=(cnt[x]!=0);
printf("%d
",res);
}
return 0;
}