链接
https://codeforces.com/gym/100783
题解
构造向量
a
a
a,如果某个距离存在,就把那个位置设置为
1
1
1,否则设置为
0
0
0
然后多项式卷积
代码
#include <bits/stdc++.h>
#define maxn 600000
#define eps 1e-8
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
struct comp
{
double x, y;
comp(double x, double y):x(x),y(y){}
comp():x(0),y(0){}
comp operator+(comp t){return comp(x+t.x, y+t.y);}
comp operator-(comp t){return comp(x-t.x, y-t.y);}
comp operator*(comp t){return comp(x*t.x-y*t.y, x*t.y+t.x*y);}
};
struct FFT
{
int up, R[maxn];
const double pi=acos(-1);
void init(int bound) //bound是积多项式的最高次幂
{
int L(0);
for(up=1;up<=bound;up<<=1,L++);
for(int i=0;i<up;i++)R[i]=(R[i>>1]>>1)|((i&1)<<(L-1));
}
void fft(comp* a, int opt)
{
int i, j, k;
comp wn, w, x, y;
for(i=0;i<up;i++)if(i>R[i])swap(a[i],a[R[i]]);
for(i=1;i<up;i<<=1)
{
wn=comp(cos(pi/i),opt*sin(pi/i));
for(j=0;j<up;j+=i<<1)
for(w=comp(1,0),k=0;k<i;k++,w=w*wn)
{
x=a[k+j], y=a[k+j+i]*w;
a[k+j]=x+y, a[k+j+i]=x-y;
}
}
if(opt==-1)for(i=0;i<up;i++)a[i].x/=up;
}
void juan(comp* a, comp* b, comp* c)
{
fft(a,1), fft(b,1);
for(int i=0;i<up;i++)c[i]=a[i]*b[i];
fft(c,-1);
}
}fft;
int read(int x=0)
{
int c, f(1);
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
comp a[maxn], b[maxn], c[maxn];
int main()
{
int n, m, i, ans, mx;
while(~scanf("%d",&n))
{
mx=0;
for(i=0;i<maxn;i++)a[i]=b[i]=c[i]=comp();
for(i=0;i<n;i++)
{
auto t=read();
b[t].x=a[t].x=1;
}
fft.init(400000);
fft.juan(a,b,c);
fft.fft(a,-1);
for(i=0;i<maxn;i++)c[i]=c[i]+a[i];
m=read();
ans=0;
while(m--)
{
auto q=read();
if(fabs(c[q].x)>1e-2)ans++;//printf("%.5lf %.5lf\n",c[q].x,c[q].y);
}
printf("%d\n",ans);
}
}