Interesting Series
题意:
定义
f
1
=
1
,
f
n
=
a
×
f
n
−
1
+
1
(
n
≥
2
)
f_1=1,f_n=a\times f_{n-1}+1(n\geq 2)
f1=1,fn=a×fn−1+1(n≥2)
输入
n
(
1
e
5
)
,
a
(
1
e
3
)
,
q
(
1
e
5
)
n(1e5),a(1e3),q(1e5)
n(1e5),a(1e3),q(1e5)
接下来输入
s
1
,
s
2
,
…
,
s
n
(
1
e
9
)
s_1,s_2,\dots,s_n(1e9)
s1,s2,…,sn(1e9)表示集合中的元素;
接下来
q
行
q行
q行
每行一个元素
k
(
1
≤
k
≤
n
)
k(1\leq k\leq n)
k(1≤k≤n),表示一个询问,求
∑
v
a
l
u
e
s
(
s
)
\sum values(s)
∑values(s)(
s
s
s表示大小为
k
k
k的子集,
v
a
l
u
e
s
(
s
)
=
f
s
u
m
(
s
)
values(s)=f_{sum(s)}
values(s)=fsum(s),
s
u
m
(
s
)
sum(s)
sum(s)表示集合元素和)。
题解:
很容易得到
f
n
=
a
n
−
1
a
−
1
f_n=\frac {a^n-1}{a-1}
fn=a−1an−1
构造母函数
(
a
s
1
x
+
1
)
×
(
a
s
2
x
+
1
)
×
⋯
×
(
a
s
n
x
+
1
)
(a^{s_1}x+1)\times(a^{s_2}x+1)\times\dots\times(a^{s_n}x+1)
(as1x+1)×(as2x+1)×⋯×(asnx+1)
这样得到
x
k
x^k
xk的系数表示选了
k
k
k个元素的
∑
a
h
e
\sum a^{he}
∑ahe然后再把它减
C
n
k
C_{n}^{k}
Cnk后除以
a
−
1
a-1
a−1就好。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ls(p) (p<<1)
#define rs(p) (p<<1|1)
const int N=1e5+9;
#define pi acos(-1.0)
#define cp complex<double>
int n,a,q;
const int mod=1e5+3;
int s[N];
vector<int>ans[N<<2];
cp b[N<<2],c[N<<2];
int frac[N],inv[N];
void init(){
frac[0]=frac[1]=inv[0]=inv[1]=1;
for(int i=2;i<mod;i++)frac[i]=1ll*frac[i-1]*i%mod,inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
for(int i=2;i<mod;i++)inv[i]=1ll*inv[i-1]*inv[i]%mod;
}
inline int C(int n,int k){
return 1ll*frac[n]*inv[k]%mod*inv[n-k]%mod;
}
int poww(int a,int b,int c){
int ans=1,base=a;
while(b){
if(b&1)ans=1ll*ans*base%c;
base=1ll*base*base%c;
b>>=1;
}
return ans;
}
int rev[N<<2];
int limit,lim;
void fft(cp *a,int type){
for(int i=0;i<limit;i++)if(i<rev[i])swap(a[i],a[rev[i]]);
for(int mid=1;mid<limit;mid<<=1){
double alpha=type*pi/mid;
for(int i=0;i<limit;i+=mid*2){
for(int j=0;j<mid;j++){
cp w(cos(alpha*j),sin(alpha*j));
cp x=a[i+j],y=a[i+j+mid]*w;
a[i+j]=x+y,a[i+j+mid]=x-y;
}
}
}
if(type==-1){
for(int i=0;i<limit;i++){
a[i]=cp((long long)(a[i].real()/limit+0.5)%mod,0);
}
}
}
void calc(cp *a,cp *b){
fft(a,1),fft(b,1);
for(int i=0;i<limit;i++)a[i]*=b[i];
fft(a,-1);
}
/*
void print(cp *a){
for(int i=0;i<10;i++)cout<<int(a[i].real()+0.5)<<" ";cout<<endl;
}*/
void solve(int p,int l,int r){
if(l==r){
ans[p].push_back(1);
ans[p].push_back(s[l]);
return;
}
int mid=(l+r)>>1,len=(r-l+2);
solve(ls(p),l,mid),solve(rs(p),mid+1,r);
limit=1,lim=0;
while(limit<=len)limit<<=1,lim++;
for(int i=0;i<limit;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<(lim-1)),b[i]=c[i]=cp(0,0);
for(int i=0;i<ans[ls(p)].size();i++)c[i]=cp(ans[ls(p)][i],0);
for(int i=0;i<ans[rs(p)].size();i++)b[i]=cp(ans[rs(p)][i],0);
calc(b,c);
for(int i=0;i<limit;i++)ans[p].push_back(int(b[i].real()+0.5));
}
int d[N];
int main(){
//freopen("tt.in","r",stdin),freopen("tt.out","w",stdout);
init();
scanf("%d%d%d",&n,&a,&q);
for(int i=1;i<=n;i++)scanf("%d",&s[i]),s[i]=poww(a,s[i],mod);
solve(1,1,n);
int inva=poww(a-1,mod-2,mod);
for(int i=1;i<=n;i++)d[i]=((long long)(ans[1][i])%mod+mod-C(n,i))*inva%mod;
while(q--){
int t;
scanf("%d",&t);
printf("%d\n",d[t]);
}
return 0;
}