思路来源
FFT详解
https://blog.csdn.net/ggn_2015/article/details/68922404
FFT代码
https://blog.csdn.net/hlyfalsy/article/details/9938547
https://blog.csdn.net/XieNaoban/article/details/69486299
FFT+NTT的理解
https://blog.csdn.net/qq_37136305/article/details/81184873
关于蝴蝶操作
https://blog.csdn.net/JuneWindy/article/details/79156335
关于IDFT矩阵的逆的证明
https://blog.csdn.net/f_zyj/article/details/76037583
FFT例题 3idiots
http://www.cnblogs.com/kuangbin/archive/2013/07/24/3210565.html
牛客十一赛例题 FFT+原根
https://blog.csdn.net/u013534123/article/details/82919834
感谢这么多答主,让我用了10h终于理解了FFT。
启发式FFT模板
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1<<18,mod=1e5+3;
double PI=acos(-1.0);
int n,a,q,k;
int c[N],s[N];
struct C{
double r,i;
C(){}
C(double a,double b){r=a,i=b;}
C operator + (C x){return C(r+x.r,i+x.i);}
C operator - (C x){return C(r-x.r,i-x.i);}
C operator * (C x){return C(r*x.r-i*x.i,r*x.i+i*x.r);}
}w[N],A[N],B[N];
int R[N];
vector <int> colors[N<<1];
struct cmp{
bool operator ()(int a,int b){
return colors[a].size()>colors[b].size();
}
};
priority_queue <int,vector<int>,cmp> heap;
void FFT(C a[],int n){
for (int i=0;i<n;i++)
if (i<R[i])
swap(a[i],a[R[i]]);
for (int t=n>>1,d=1;d<n;d<<=1,t>>=1)
for (int i=0;i<n;i+=(d<<1))
for (int j=0;j<d;j++){
C tmp=w[t*j]*a[i+j+d];
a[i+j+d]=a[i+j]-tmp;
a[i+j]=a[i+j]+tmp;
}
}
void FFT_times(vector <int> &a,vector <int> &b,vector <int> &c){
int n,d;
for (int i=0;i<a.size();i++)
A[i]=C(a[i],0);
for (int i=0;i<b.size();i++)
B[i]=C(b[i],0);
for (n=1,d=0;n<a.size()+b.size()-1;n<<=1,d++);
for (int i=0;i<n;i++){
R[i]=(R[i>>1]>>1)|((i&1)<<(d-1));
w[i]=C(cos(2*PI*i/n),sin(2*PI*i/n));
}
for (int i=a.size();i<n;i++)
A[i]=C(0,0);
for (int i=b.size();i<n;i++)
B[i]=C(0,0);
FFT(A,n),FFT(B,n);
for (int i=0;i<n;i++)
A[i]=A[i]*B[i],w[i].i*=-1.0;
FFT(A,n);
c.clear();
for (int i=0;i<=a.size()+b.size()-2;i++)
c.push_back(((LL)(A[i].r/n+0.5))%mod);
}
int modpow(int x,int n,int mod)
{
int res=1;
for(;n;n>>=1,x=1ll*x*x%mod)
if(n&1)res=1ll*res*x%mod;
return res;
}
int main(){
scanf("%d%d%d",&n,&a,&q);
for(int i=1;i<=n;++i)
scanf("%d",&s[i]);
while (!heap.empty())
heap.pop();
int sz=0;
for (int i=1;i<=n;i++){
colors[++sz].clear();
colors[sz].push_back(modpow(a,s[i],mod));
colors[sz].push_back(1);
heap.push(sz);
}
while (heap.size()>=2){
int x=heap.top();
heap.pop();
int y=heap.top();
heap.pop();
FFT_times(colors[x],colors[y],colors[++sz]);
colors[x].clear(),colors[y].clear();
heap.push(sz);
}
c[0]=1;//C(n,0)
for(int i=1;i<=n;++i)
c[i]=1ll*c[i-1]*(n-i+1)%mod*modpow(i,mod-2,mod)%mod;
int inv=modpow(1-a+mod,mod-2,mod);
for(int i=1;i<=q;++i)
{
scanf("%d",&k);
int res=(c[k]-colors[sz][n-k]+mod)%mod;
res=1ll*res*inv%mod;
printf("%d\n",res);
}
return 0;
}