首页 > 其他 > 详细

AGC021F Trinity

时间:2020-05-13 20:28:55      阅读:46      评论:0      收藏:0      [点我收藏+]

Link
\(f_{i,j}\)\(i\)\(j\)列,强制每行都有黑格子的方案数,那么答案就是\(\sum\limits_{i=1}^n{n\choose i}f_{i,m}\)
考虑\(f_{i,j}\)新增一列转移到\(f_{i+k,j+1}\)有哪些情况:
\(k=0\),那么相当于在第\(j\)列选\(0\sim2\)个端点,贡献系数为\(1+i+{i\choose2}\)
\(k>0\),那么我们考虑求\(b_{j+1}-1,c_{j+1}+1\)不同的方案。注意这两个格子都是白色的,因此不会在多出来的\(k\)行,贡献系数为\({i+k+2\choose k+2}\)。具体来说是在\(i+k+2\)行(因为是\(b_j-1,c_j+1\))中选\(k+2\)行,把最上/下面一行作为\(b_{j+1}-1,c_{j+1}+1\),中间的\(k\)行作为新的\(k\)行。
注意到第二部分的转移是一个卷积的形式,NTT优化即可。

#include<cctype>
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=1<<14|1,P=998244353;
int n,m,lim,fac[N],ifac[N],w[N],rev[N],f[N],g[N],t[N];
int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
void inc(int&a,int b){a+=b-P,a+=a>>31&P;}
void dec(int&a,int b){a-=b,a+=a>>31&P;}
void mul(int&a,int b){a=1ll*a*b%P;}
int pow(int a,int b){int r=1;for(;b;b>>=1,mul(a,a))if(b&1)mul(r,a);return r;}
void init(int n)
{
    int half=(lim=1<<(33-__builtin_clz(n)))/2,g=pow(3,(P-1)/lim);
    w[half]=fac[0]=ifac[0]=1;
    for(int i=1;i<lim;++i) rev[i]=(rev[i>>1]>>1)|(i&1? half:0),mul(fac[i]=fac[i-1],i),ifac[i]=pow(fac[i],P-2);
    for(int i=half+1;i<lim;++i) mul(w[i]=w[i-1],g);
    for(int i=half-1;i;--i) w[i]=w[i<<1];
}
void NTT(int*a,int f)
{
    if(!~f) std::reverse(a+1,a+lim);
    for(int i=1;i<lim;++i) if(i<rev[i]) std::swap(a[i],a[rev[i]]);
    for(int i=1;i<lim;i<<=1) for(int j=0,d=i<<1;j<lim;j+=d) for(int k=0,x;k<i;++k) x=1ll*a[i+j+k]*w[i+k]%P,dec(a[i+j+k]=a[j+k],x),inc(a[j+k],x);
    if(!~f) for(int i=0,x=P-(P-1)/lim;i<lim;++i) mul(a[i],x);
}
int main()
{
    int n=read(),m=read(),ans=0;
    init(n),memcpy(g+1,ifac+3,4*n),NTT(g,1),f[0]=t[0]=1;
    for(int i=1;i<=m;++i)
    {
	NTT(f,1);
	for(int j=0;j<lim;++j) mul(f[j],g[j]);
	NTT(f,-1);
        for(int j=0;j<=n;++j) t[j]=(1ll*f[j]*fac[j+2]+t[j]*(j*(j+1)/2+1ll))%P,mul(f[j]=t[j],ifac[j]);
	memset(f+n+1,0,4*(lim-n-1));
    }
    for(int i=0;i<=n;++i) inc(ans,1ll*ifac[i]*ifac[n-i]%P*t[i]%P);
    mul(ans,fac[n]),printf("%d",ans);
}

AGC021F Trinity

原文:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12884627.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!