Luogu P5339 [TJOI2019]唱跳rap和篮球

Posted cjjsb

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P5339 [TJOI2019]唱跳rap和篮球相关的知识,希望对你有一定的参考价值。

这看题目一眼容斥,令聊唱、跳、rap和篮球的组数至少(x)的方案数为(g(x))

那么显然(Ans=sum_{i=0}^{min(lfloor frac{n}{4} floor,a,b,c,d)} (-1)^ig(i)),考虑如何计算(g(x))

先考虑放下给定的(x)组,显然它们的顺序是唯一的,也就是确定了第一个就能确定后面的

相当于现在连续的(4)个位置变成了选第一个位置,因此方案数是(C_{n-3x}^x)

那么剩下的(n-4x)个数怎么办,可重全排列

[sum_{i=0}^{a-x}sum_{j=0}^{b-x}sum_{p=0}^{c-x}sum_{q=0}^{d-x} [i+j+p+q=n-4x]frac{(n-4x)!}{i!j!p!q!}]

[=(n-4x)! imessum_{i=0}^{a-x}sum_{j=0}^{b-x}sum_{p=0}^{c-x}sum_{q=0}^{d-x}[i+j+p+q=n-4x] frac{1}{i!} imes frac{1}{j!} imes frac{1}{p!} imes frac{1}{q!}]

显然后面的部分是一个卷积的形式,由于数据范围小直接暴力卷即可

#include<cstdio>
#include<iostream>
#include<cstring>
#define RI register int
#define CI const int&
#define Ms(f,x) memset(f,x,sizeof(f))
using namespace std;
const int N=1005,mod=998244353;
int n,A,B,C,D,a[N],b[N],c[N],d[N],fact[N],inv[N],len,ret,ans,lim;
inline void inc(int& x,CI y)
{
    if ((x+=y)>=mod) x-=mod;
}
inline void dec(int& x,CI y)
{
    if ((x-=y)<0) x+=mod;
}
inline int quick_pow(int x,int p=mod-2,int mul=1)
{
    for (;p;p>>=1,x=1LL*x*x%mod) if (p&1) mul=1LL*mul*x%mod; return mul;
}
inline void init(CI n)
{
    RI i; for (fact[0]=i=1;i<=n;++i) fact[i]=1LL*fact[i-1]*i%mod;
    for (inv[n]=quick_pow(fact[n]),i=n-1;~i;--i) inv[i]=1LL*inv[i+1]*(i+1)%mod;
}
inline int Comb(CI n,CI m)
{
    return 1LL*fact[n]*inv[m]%mod*inv[n-m]%mod;
}
inline void conv(int *a,int& la,int *b,CI lb,CI n)
{
    RI i,j; static int r[N]; Ms(r,0);
    for (i=0;i<=la;++i) for (j=0;j<=lb;++j)
    if (i+j<=n) inc(r[i+j],1LL*a[i]*b[j]%mod);
    la=min(n,la+lb); for (i=0;i<=la;++i) a[i]=r[i];
}
inline int calc(CI n,CI x)
{
    RI i; Ms(a,0); Ms(b,0); Ms(c,0); Ms(d,0);
    for (i=0;i<=A-x;++i) a[i]=inv[i]; for (i=0;i<=B-x;++i) b[i]=inv[i];
    for (i=0;i<=C-x;++i) c[i]=inv[i]; for (i=0;i<=D-x;++i) d[i]=inv[i];
    len=A-x; conv(a,len,b,B-x,n); conv(a,len,c,C-x,n); conv(a,len,d,D-x,n); return a[n];
}
int main()
{
    scanf("%d%d%d%d%d",&n,&A,&B,&C,&D); init(n);
    RI i; lim=min(n/4,min(min(A,B),min(C,D)));
    for (i=0;i<=lim;++i) ret=1LL*Comb(n-3*i,i)*fact[n-4*i]%mod*calc(n-4*i,i)%mod,
    i&1?(dec(ans,ret),0):(inc(ans,ret),0); return printf("%d",ans),0;
}

以上是关于Luogu P5339 [TJOI2019]唱跳rap和篮球的主要内容,如果未能解决你的问题,请参考以下文章

题解Luogu P5339 [TJOI2019]唱跳rap和篮球

[luogu5339] [TJOI2019]唱跳rap和篮球(容斥原理+组合数学)(不用NTT)

TJOI 2019唱跳rap和篮球

[TJOI2019]唱跳rap和篮球

[TJOI2019]唱跳rap和篮球——NTT+生成函数+容斥

[TJOI2019]唱跳rap和篮球——容斥原理+生成函数