代码中这一部分
int lim=1,limbit=0;
for(lim=1,limbit=0;lim<=(L<<1);lim<<=1,++limbit);
for(int i=1;i<lim;i++) revid[i]=(revid[i>>1]>>1)|((i&1)<<(limbit-1));
( L=min(m,n/S) )
lim<=(L<<1)写成lim<=(L<<1)或者lim<(L<<1)+2能够通过,但是写成lim<(L<<1)会WA掉两个点。
做乘项最高不是2倍么?为什么我只写小于号会WA?
#include<bits/stdc++.h>
#define ll long long
#define uit unsigned int
using namespace std;
const int N=1e7+10;
const ll mod=1004535809ll;
int n,m,S,L,revid[N];ll pw[N],cir[N],F[N],G[N],W[N],ans=0;
ll ftp(ll b,ll p){
ll r=1;
while(p){
if(p&1) r=r*b%mod;
b=b*b%mod;
p>>=1;
}
return r;
}
ll inverse(ll b,ll mod){
return ftp(b,mod-2);
}
void NTT(int len,ll *arr,int sign){
for(int i=0;i<len;i++){
if(i<revid[i]){
swap(arr[i],arr[revid[i]]);
}
}
for(int l=2;l<=len;l<<=1){
ll Wn=ftp((sign==1)?3:inverse(3,mod),(mod-1ll)/l);
for(int be=0;be<len;be+=l){
ll w=1;
for(int i=0;i<(l>>1);i++,w=w*Wn%mod){
ll tmp1=arr[be+i],tmp2=arr[be+i+(l>>1)]*w%mod;
arr[be+i]=(tmp1+tmp2)%mod;
arr[be+i+(l>>1)]=((tmp1-tmp2)%mod+mod)%mod;
}
}
}
if(sign==-1){
ll inv=inverse(len,mod);
for(int i=0;i<len;i++) arr[i]=arr[i]*inv%mod;
}
}
ll C(int x,int y){
if(x<y||x<0||y<0) return 0;
return pw[x]*cir[y]%mod*cir[x-y]%mod;
}
int main(){
//freopen(".in","r",stdin);
//freopen("345.out","w",stdout);
pw[0]=1ll;for(int i=1;i<N;i++) pw[i]=1ll*pw[i-1]*i%mod;
cir[N-1]=ftp(pw[N-1],mod-2);for(int i=N-2;i>=0;i--) cir[i]=1ll*cir[i+1]*(i+1)%mod;
scanf("%d%d%d",&n,&m,&S);
L=min(m,n/S);
for(int i=0;i<=m;i++) scanf("%lld",&W[i]);
for(int i=0;i<=L;i++){
F[i]=C(m,i)*pw[n]%mod*ftp(ftp(pw[S],i)*pw[n-S*i]%mod,mod-2)%mod*ftp(m-i,n-S*i)%mod;
F[i]=F[i]*pw[i]%mod;
G[i]=(i&1)?(mod-cir[i])%mod:cir[i];
}
/*
cout<<endl;
for(int i=0;i<=L;i++){
cout<<F[i]<<' ';
}
cout<<endl;
for(int i=0;i<=L;i++){
cout<<G[i]<<' ';
}
cout<<endl;
*/
reverse(F,F+L+1);
int lim=1,limbit=0;
for(lim=1,limbit=0;lim<=(L<<1);lim<<=1,++limbit);
for(int i=1;i<lim;i++) revid[i]=(revid[i>>1]>>1)|((i&1)<<(limbit-1));
NTT(lim,F,1);NTT(lim,G,1);
for(int i=0;i<lim;i++) F[i]=F[i]*G[i]%mod;
/*
cout<<endl;
for(int i=0;i<lim;i++){
cout<<F[i]<<' ';
}
cout<<endl;
*/
NTT(lim,F,-1);
/*
cout<<endl;
for(int i=0;i<=L;i++) cout<<F[i]<<' ';
cout<<endl;
*/
reverse(F,F+L+1);
for(int i=0;i<=L;i++){
ans=(ans+F[i]*cir[i]%mod*W[i]%mod)%mod;
}
printf("%lld\n",ans);
return 0;
}