[LOJ3106][TJOI2019]唱、跳、rap和篮球:DP+生成函数+NTT+容斥原理
分析
令\(f(i)\)表示共\(i\)组同学讨论cxk的位置的方案数(不考虑其他位置上的人的爱好),这个数组可以很容易地通过依次考虑每个位置是否是四个人中最后一个人的位置来递推求解,时间复杂度\(O(n^2)\)。
令\(g(i)\)表示共\(i\)组同学讨论cxk,剩下的\(n-4i\)个位置上的人的爱好的方案数。这个数组可以通过对每种情况,分别写出四种爱好的\(EGF\),然后\(NTT\)合并求解,时间复杂度\(O(n^2 \log n)\)。
统计答案的话很简单,容斥一下就好了:
\]
代码
#include <bits/stdc++.h>
#define rin(i,a,b) for(int i=(a);i<=(b);++i)
#define irin(i,a,b) for(int i=(a);i>=(b);--i)
#define trav(i,a) for(int i=head[a];i;i=e[i].nxt)
#define Size(a) (int)a.size()
#define pb push_back
#define mkpr std::make_pair
#define fi first
#define se second
#define lowbit(a) ((a)&(-(a)))
typedef long long LL;
using std::cerr;
using std::endl;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const int MAXN=1005;
const int NTT=1048576;
const int MOD=998244353;
const int G=3,INVG=332748118;
int N,a,b,c,d;
int n,m,len,rev[MAXN<<2];
int w[NTT+5],iw[NTT+5];
int fac[MAXN],invf[MAXN];
int f[MAXN][MAXN],g[MAXN];
int A[MAXN<<2],B[MAXN<<2],C[MAXN<<2],D[MAXN<<2];
inline int add(int x,int y){
return x+y<MOD?x+y:x+y-MOD;
}
inline int mns(int x,int y){
return x-y>=0?x-y:x-y+MOD;
}
inline int qpow(int x,int y){
int ret=1,tt=x%MOD;
while(y){
if(y&1)ret=1ll*ret*tt%MOD;
tt=1ll*tt*tt%MOD;
y>>=1;
}
return ret;
}
void ntt(int *c,int dft){
rin(i,0,n-1)if(i<rev[i])std::swap(c[i],c[rev[i]]);
for(int mid=1;mid<n;mid<<=1){
int r=(mid<<1),u=NTT/r;
for(int l=0;l<n;l+=r){
for(int i=0,v=0;i<mid;++i,v+=u){
int x=c[l+i],y=1ll*c[l+mid+i]*(dft>0?w[v]:iw[v])%MOD;
c[l+i]=add(x,y);
c[l+mid+i]=mns(x,y);
}
}
}
if(dft<0){
int invn=qpow(n,MOD-2);
rin(i,0,n-1)c[i]=1ll*c[i]*invn%MOD;
}
}
void init(){
fac[0]=1;rin(i,1,N)fac[i]=1ll*fac[i-1]*i%MOD;
invf[N]=qpow(fac[N],MOD-2);irin(i,N-1,0)invf[i]=1ll*invf[i+1]*(i+1)%MOD;
w[0]=iw[0]=1;w[1]=qpow(G,(MOD-1)/NTT);iw[1]=qpow(INVG,(MOD-1)/NTT);
rin(i,2,NTT-1)w[i]=1ll*w[i-1]*w[1]%MOD,iw[i]=1ll*iw[i-1]*iw[1]%MOD;
}
void prepare(){
for(n=1,len=0;n<=m;n<<=1,++len);
rin(i,1,n-1)rev[i]=((rev[i>>1]>>1)|((i&1)<<(len-1)));
}
int main(){
N=read(),a=read(),b=read(),c=read(),d=read();
init();
int lim=std::min(N/4,std::min(std::min(a,b),std::min(c,d)));
f[0][0]=1;
rin(i,1,N){
rin(j,0,lim){
f[i][j]=f[i-1][j];
if(j&&i>3)f[i][j]=add(f[i][j],f[i-4][j-1]);
}
}
rin(i,0,lim){
m=a-i+b-i+c-i+d-i;prepare();
rin(j,0,a-i)A[j]=invf[j];
rin(j,0,b-i)B[j]=invf[j];
rin(j,0,c-i)C[j]=invf[j];
rin(j,0,d-i)D[j]=invf[j];
ntt(A,1);ntt(B,1);ntt(C,1);ntt(D,1);
rin(j,0,n-1)A[j]=1ll*A[j]*B[j]%MOD*C[j]%MOD*D[j]%MOD;;
ntt(A,-1);
g[i]=1ll*A[N-i*4]*fac[N-i*4]%MOD;
memset(A,0,n*sizeof(int));
memset(B,0,n*sizeof(int));
memset(C,0,n*sizeof(int));
memset(D,0,n*sizeof(int));
}
int ans=0,sgn=MOD-1;
rin(i,0,lim){
sgn=MOD-sgn;
ans=(ans+1ll*sgn*f[N][i]%MOD*g[i])%MOD;
}
printf("%d\n",ans);
return 0;
}
[LOJ3106][TJOI2019]唱、跳、rap和篮球:DP+生成函数+NTT+容斥原理的更多相关文章
- [TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt
[TJOI2019]唱.跳.rap和篮球 这么多人过没人写题解啊 那我就随便说说了嗷 这题第一步挺套路的,就是题目要求不能存在balabala的时候考虑正难则反,要求必须存在的方案数然后用总数减,往往 ...
- [bzoj5510]唱跳rap和篮球
显然答案可以理解为有(不是仅有)0对情况-1对情况+2对情况-- 考虑这个怎么计算,先计算这t对情况的位置,有c(n-3t,t)种情况(可以理解为将这4个点缩为1个,然后再从中选t个位置),然后相当于 ...
- Luogu5339 [TJOI2019]唱、跳、rap和篮球 【生成函数,NTT】
当时看到这道题的时候我的脑子可能是这样的: My left brain has nothing right, and my right brain has nothing left. 总之,看到&qu ...
- [TJOI2019]唱,跳,rap,篮球(生成函数,组合数学,NTT)
算是补了个万年大坑了吧. 根据 wwj 的题解(最准确),设一个方案 \(S\)(不一定合法)的鸡你太美组数为 \(w(S)\). 答案就是 \(\sum\limits_{S}[w(S)=0]\). ...
- 将Android手机无线连接到Ubuntu实现唱跳Rap
您想要将Android设备连接到Ubuntu以传输文件.查看Android通知.以及从Ubuntu桌面发送短信 – 你会怎么做?将文件从手机传输到PC时不要打电话给自己:使用GSConnect就可以. ...
- [TJOI2019]唱、跳、rap和篮球——NTT+生成函数+容斥
题目链接: [TJOI2019]唱.跳.rap和篮球 直接求不好求,我们考虑容斥,求出至少有$i$个聚集区间的方案数$ans_{i}$,那么最终答案就是$\sum\limits_{i=0}^{n}(- ...
- [luogu5339] [TJOI2019]唱、跳、rap和篮球(容斥原理+组合数学)(不用NTT)
[luogu5339] [TJOI2019]唱.跳.rap和篮球(容斥原理+组合数学)(不用NTT) 题面 略 分析 首先考虑容斥,求出有i堆人讨论的方案. 可以用捆绑法,把每堆4个人捆绑成一组,其他 ...
- 「TJOI2019」唱、跳、rap 和篮球 题解
题意就不用讲了吧-- 鸡你太美!!! 题意: 有 \(4\) 种喜好不同的人,分别最爱唱.跳. \(rap\).篮球,他们个数分别为 \(A,B,C,D\) ,现从他们中挑选出 \(n\) 个人并进行 ...
- [BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT)
[BZOJ 3992] [SDOI 2015] 序列统计(DP+原根+NTT) 题面 小C有一个集合S,里面的元素都是小于质数M的非负整数.他用程序编写了一个数列生成器,可以生成一个长度为N的数列,数 ...
随机推荐
- 从入门到自闭之Python高阶函数
高阶函数:内部帮忙做了一个for循环 filter:筛选过滤 语法: filter(function,iterable) function: 1.指定过滤规则(函数的内存地址) 2.用来筛选的函数,在 ...
- 如何用纯 CSS 创作出平滑的层叠海浪特效
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/JvmBdE 可交互视频教 ...
- 在Windows下安装BIND作为DNS服务器(模拟网站比较有用)
本文参考了CU下的一篇帖子,感谢:) 1.下载BIND http://ftp.isc.org/isc/bind9/9.4.3/BIND9.4.3.zip 2.安装 下载回来是zip的压缩包,解压 ...
- 从尾到头打印列表——牛客剑指offer
题目描述 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList. 解题思路 思路1: 顺序遍历链表,取出每个结点的数据,插入list中. 由于要求list倒序存储链表中的数据,而我们是顺序取 ...
- 配置Mysql远程连接
一.赋予某个用户权限 1.赋予权限格式:grant 权限 on 数据库对象 to 用户@IP(或者相应正则) 注:可以赋予select,delete,update,insert,index等权限精确到 ...
- AGC009E Eternal Average
atc 神题orz 那个擦掉\(k\)个数然后写上一个平均值可以看成是\(k\)叉Huffman树的构造过程,每次选\(k\)个点合成一个新点,然后权值设为平均值.这些0和1都会在叶子的位置,同时每个 ...
- 【版本控制工具】 Git进阶1
一.Git常用命令 Git中的很多命令与Linux相同(比如修改,查询,编辑,移动等),这里可以参考我之前的一篇文章https://www.cnblogs.com/ywb-articles/p/105 ...
- MixNet学习笔记
最近,谷歌使用了AutoML,推出了一种新网络:MixNet,其论文为<MixNet: Mixed Depthwise Convolutional Kernels>.其主要创新点是,研究不 ...
- 安全专家发现GE Multilin SR的一个关键漏洞对全球电网构成严重威胁。
A team of researchers from New York University has found a serious vulnerability in some of GE Multi ...
- Centos的yum源更换为阿里云源
1.备份 # mv /etc/yum.repos.d/CentOS-Base.repo # /etc/yum.repos.d/CentOS-Base.repo.backup 2.下载新的CentOS- ...