请问我这样写是漏项了么?
查看原帖
请问我这样写是漏项了么?
514939
Cafard楼主2022/6/3 09:52

代码中这一部分

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;
}

2022/6/3 09:52
加载中...