记录编号 578118 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [HAOI 2018]染色 最终得分 100
用户昵称 Gravatarop_组撒头屯 是否通过 通过
代码语言 C++ 运行时间 1.955 s
提交时间 2023-02-01 20:22:10 内存使用 111.36 MiB
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define ld long double
#define pii pair<int,int>
#define vi vector<int>
#define si set<int>
#define qi queue<int>
#define sti stack<int>
#define fi first
#define se second
#define pb push_back
#define clr(f,n) memset(f,0,sizeof(int)*(n))
#define cpy(f,g,n) memcpy(f,g,sizeof(int)*(n))
const int N=(1<<17)+5;
const int M=10000000+5;
const ll mod=1004535809;
ll fst(ll x,ll y){
    ll ans=1;
    while(y){
        if (y&1)ans=ans*x%mod;
        x=x*x%mod;
        y>>=1;
    }
    return ans;
}
const ll _G=3;
const ll invG=fst(_G,mod-2);
int tr[N<<1],tf=0;
ll fac[M],inv[M];
void init(int n){
    fac[0]=1;
    for (int i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;
    inv[n]=fst(fac[n],mod-2);
    for (int i=n-1;i>=0;i--)inv[i]=inv[i+1]*(i+1)%mod;
}
void tpre(int n){
    if (n==tf)return ;
    for (int i=0;i<n;i++)tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
    tf=n;
}
void NTT(ll *g,int n,bool opt){
    static ll f[N<<1],w[N<<1];
    tpre(n);w[0]=1;
    for (int i=0;i<n;i++)f[i]=g[tr[i]];
    for (int p=2;p<=n;p<<=1){
        int len=p>>1;
        ll tG=fst(opt?_G:invG,(mod-1)/p);
        for (int i=1;i<len;i++)w[i]=w[i-1]*tG%mod;
        for (int i=0;i<n;i+=p){
            for (int j=i;j<i+len;j++){
                ll now=f[j+len]*w[j-i]%mod;
                f[j+len]=(f[j]-now+mod)%mod;
                f[j]=(f[j]+now)%mod;
            }
        }
    }
    if (opt)for (int i=0;i<n;i++)g[i]=f[i];
    else{
        ll invn=fst(n,mod-2);
        for (int i=0;i<n;i++)g[i]=f[i]*invn%mod;
    }
}
void px(ll *f,ll *g,int n){
    for (int i=0;i<n;i++)f[i]=f[i]*g[i]%mod;
}
void times(ll *f,ll *g,int len,int lim){
    static ll sav[N<<1];
    int n=1;for (;n<=len;n<<=1);
    clr(sav,n);cpy(sav,g,n);
    NTT(f,n,1);NTT(sav,n,1);
    px(f,sav,n);NTT(f,n,0);
    if (lim)clr(f+lim,n-lim);
    clr(sav,n);
}
int n,m,s;
ll a[N<<1],b[N<<1],w[N<<1];
ll C(int x,int y){
    return fac[x]*inv[y]%mod*inv[x-y]%mod;
}
ll g(int i){
    if (n-i*s<0)return 0;
    return C(m,i)*fac[n]%mod*inv[n-i*s]%mod*fst(inv[s],i)%mod*fst(m-i,n-i*s)%mod;
}
int main(){
	freopen ("2018color.in","r",stdin);
	freopen ("2018color.out","w",stdout);
	scanf("%d%d%d",&n,&m,&s);
	for (int i=0;i<=m;i++)scanf("%lld",&w[i]);
	init(max(n,m));
	for (int i=0;i<=m;i++){
	    a[i]=fac[i]*g(i);
	    b[i]=(i&1)?mod-inv[i]:inv[i];
    }
    reverse(a,a+m+1);
    times(a,b,m<<1,m+1);
    reverse(a,a+m+1);
    ll ans=0;
    for (int i=0;i<=m;i++)ans=(ans+a[i]*inv[i]%mod*w[i]%mod)%mod;
    printf("%lld\n",ans);
    return 0;
}