做法
分治+FFT优化。
按照值域分治即可。
代码
=> 提交了整整一页,一直在查TLE和测速 =.=
=> 先是一个奇怪卡精(?),复数类里long double改成double就能过,否则会T。不清楚为什么(
=> 其次发现自己的FFT实在跑得太慢了。。。好像是我写FFT的姿势不对,于是稍微改动了一下。似乎变快了1000+ms..
#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x); i<=(y); i++)
#define ll long long
#define ld long double
#define inf 1000000000
#define mset(x,y) memset((x),(y),sizeof(x))
using namespace std;
const ld pi=acos(-1);
ll read(){
char ch=getchar(); ll x=0; int op=1;
for (; !isdigit(ch); ch=getchar()) if (ch=='-') op=-1;
for (; isdigit(ch); ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*op;
}
#define N 131072
int n,A[N],B[N],r[N]; ll ans[N];
struct comp{
double a,b; comp(){} comp(double a_,double b_){ a=a_,b=b_; }
comp operator + (const comp &t){ return comp(a+t.a,b+t.b); }
comp operator - (const comp &t){ return comp(a-t.a,b-t.b); }
comp operator * (const comp &t){ return comp(a*t.a-b*t.b,a*t.b+b*t.a); }
}a[N],b[N],w[N];
void pre(int n){
w[n]=comp(1,0);
rep (i,0,n-1){
w[i]=comp(cos(2*i*pi/n),sin(2*i*pi/n));
r[i]=(r[i>>1]>>1)|((i&1)*(n>>1));
a[i]=b[i]=comp(0,0);
}
}
void fft(comp a[],int All,int fl){
rep (i,0,All-1) if (i<r[i]) swap(a[i],a[r[i]]);
int n=2,m=1,x=All>>1;
for (; n<=All; m=n,n<<=1,x>>=1)
for (int i=0; i<All; i+=n)
for (int k=0; k<m; k++){
comp t=(fl?w[All-x*k]:w[x*k])*a[i+m+k];
a[i+m+k]=a[i+k]-t;
a[i+k]=a[i+k]+t;
}
}
void work(int l,int r){
if (l==r){ ans[0]+=(ll)A[l]*B[l]; return; }
int mid=l+r>>1;
int n1=mid-l,m1=r-mid-1;
n=1; for (; n<=n1+m1; n<<=1); pre(n);
rep (i,l,mid) a[i-l]=comp(A[i],0);
rep (i,mid+1,r) b[i-mid-1]=comp(B[i],0);
fft(a,n,0); fft(b,n,0);
rep (i,0,n-1) a[i]=a[i]*b[i];
fft(a,n,1);
rep (i,0,r-l-1) ans[i+l+mid+1]+=(ll)(a[i].a/n+0.5);
rep (i,0,n-1) a[i]=b[i]=comp(0,0);
rep (i,mid+1,r) a[i-mid-1]=comp(A[i],0);
rep (i,l,mid) b[mid-i]=comp(B[i],0);
fft(a,n,0); fft(b,n,0);
rep (i,0,n-1) a[i]=a[i]*b[i];
fft(a,n,1);
rep (i,0,r-l-1) ans[i+1]+=(ll)(a[i].a/n+0.5);
work(l,mid); work(mid+1,r);
}
void solve(){
int n=read(),m=read(),q=read();
mset(A,0); mset(B,0); mset(ans,0);
rep (i,1,n) A[read()]++;
rep (i,1,m) B[read()]++;
work(0,50000);
while (q--) printf("%lld\n",ans[read()]);
}
int main(){
int T=read(); while (T--) solve();
return 0;
}