[TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt
[TJOI2019]唱、跳、rap和篮球
这么多人过没人写题解啊
那我就随便说说了嗷
这题第一步挺套路的,就是题目要求不能存在balabala的时候考虑正难则反,要求必须存在的方案数然后用总数减,往往更简单。
这个题呢直接要求存在发现还不咋好求,反正就是存在嘛我们就容斥好了。
呐,我们就枚举至少有多少段(唱跳rap篮球)。
假设有\(i\)段,那么枚举一下这\(i\)段的位置,这是\(\binom{n-3i}{i}\)的。
就相当于给定长度为\(n-3i\)的空格,选出\(i\)个空格为(唱跳rap篮球)的起始点就好了。
假设每种人分别有\(num[1]\)到\(num[4]\)个,把他们都\(-i\),就相当于求剩下这些人随意排列的方案数咯。
假设第\(i\)种人用了\(now[i]\)个,那么方案数为
\(\frac{(n-4i)!}{\prod now[j]!}\)。
这东西就是拿生成函数搞一搞就好了。
就是第一个人的生成函数是\(\sum\limits_{i=0}^{num[1]} \frac{x^i}{i!}\)。
把这四个生成函数乘一起,最后返回第\(n-4i\)项乘以\((n-4i)!\)就好啦。
贴个代码
#include <bits/stdc++.h>
#define N 1010
using namespace std;
typedef long long ll;
const int mod = 998244353 ;
int C[N][N],num[5],len[5],fac[N<<2],inv[N<<2],b[5][N<<2];
int n;
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd() {int x=0,f=1; char c=nc(); while(c<48) {if(c=='-') f=-1; c=nc();} while(c>47) x=(((x<<2)+x)<<1)+(c^48),c=nc(); return x*f;}
int qpow(int x,int y)
{
	int ans=1;
	while(y)
	{
		if(y&1) ans=(ll)ans*x%mod;
		y>>=1;
		x=(ll)x*x%mod;
	}
	return ans;
}
void init()
{
	fac[0]=1; for(int i=1;i<=1000;i++) fac[i]=(ll)fac[i-1]*i%mod;
	inv[0]=1; for(int i=1;i<=1000;i++) inv[i]=qpow(fac[i],mod-2);
}
void ntt(int *a,int len,int flg)
{
	int i,j,k,t,w,x,tmp;
	for(i=k=0;i<len;i++)
	{
		if(i>k) swap(a[i],a[k]);
		for(j=len>>1;(k^=j)<j;j>>=1);
	}
	for(k=2;k<=len;k<<=1)
	{
		t=k>>1;
		x=qpow(3,(mod-1)/k);
		if(flg==-1) x=qpow(x,mod-2);
		for(i=0;i<len;i+=k)
			for(j=i,w=1;j<i+t;j++)
			{
				tmp=(ll)a[j+t]*w%mod;
				a[j+t]=(a[j]-tmp+mod)%mod;
				a[j]=(a[j]+tmp)%mod;
				w=(ll)w*x%mod;
			}
	}
	if(flg==-1) for(t=qpow(len,mod-2),i=0;i<len;i++) a[i]=(ll)a[i]*t%mod;
}
int calc(int k)
{
	int l=1;
	while(l<=max((num[4]-k)<<1,(n-4*k)<<1)) l<<=1;
	while(l<=(num[4]<<2)) l<<=1;
	for(int i=1;i<=4;i++)
	{
		len[i]=num[i]-k;
		for(int j=0;j<=l;j++) b[i][j]=0;
	}
	for(int i=1;i<=4;i++) for(int j=0;j<=len[i];j++) b[i][j]=inv[j];
	for(int i=1;i<=4;i++) ntt(b[i],l,1);
	for(int i=2;i<=4;i++) for(int j=0;j<l;j++) b[1][j]=(ll)b[1][j]*b[i][j]%mod;
	ntt(b[1],l,-1);
	return (ll)b[1][n-4*k]*fac[n-4*k]%mod;
}
int main()
{
	n=rd(); for(int i=1;i<=4;i++) num[i]=rd();
	for(int i=0;i<=n;i++)
	{
		C[i][0]=1;
		for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
	}
	sort(num+1,num+5);
	int l=1;
	while(l<=(num[4]<<2)) l<<=1;
	init();
	int ans=0;
	for(int i=0;(i<<2)<=min(n,num[1]<<2);i++)
	{
		int mdl=(ll)calc(i)*C[n-3*i][i]%mod;
		if(i&1) (ans-=mdl)%=mod;
		else (ans+=mdl)%=mod;
	}
	printf("%d\n",(ans+mod)%mod);
	return 0;
}
												
											[TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt的更多相关文章
- [bzoj5510]唱跳rap和篮球
		
显然答案可以理解为有(不是仅有)0对情况-1对情况+2对情况-- 考虑这个怎么计算,先计算这t对情况的位置,有c(n-3t,t)种情况(可以理解为将这4个点缩为1个,然后再从中选t个位置),然后相当于 ...
 - [TJOI2019]唱、跳、rap和篮球——NTT+生成函数+容斥
		
题目链接: [TJOI2019]唱.跳.rap和篮球 直接求不好求,我们考虑容斥,求出至少有$i$个聚集区间的方案数$ans_{i}$,那么最终答案就是$\sum\limits_{i=0}^{n}(- ...
 - 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就可以. ...
 - [luogu5339] [TJOI2019]唱、跳、rap和篮球(容斥原理+组合数学)(不用NTT)
		
[luogu5339] [TJOI2019]唱.跳.rap和篮球(容斥原理+组合数学)(不用NTT) 题面 略 分析 首先考虑容斥,求出有i堆人讨论的方案. 可以用捆绑法,把每堆4个人捆绑成一组,其他 ...
 - 「TJOI2019」唱、跳、rap 和篮球 题解
		
题意就不用讲了吧-- 鸡你太美!!! 题意: 有 \(4\) 种喜好不同的人,分别最爱唱.跳. \(rap\).篮球,他们个数分别为 \(A,B,C,D\) ,现从他们中挑选出 \(n\) 个人并进行 ...
 - Oracle学习总结_day03_day04_条件查询_排序_函数_子查询
		
本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day03_条件查询_排序_函数 清空回收站: PUR ...
 - C Primer Plus_第6章_循环_编程练习
		
1.题略 #include int main(void) { int i; char ch[26]; for (i = 97; i <= (97+25); i++) { ch[i-97] = i ...
 
随机推荐
- layuiadmin更新echarts
			
发现layuiadmin中echarts版本有些老了,对其中的echarts进行了更新: 查询当前echarts版本: console.log(echarts.version); 1.前往echart ...
 - javaEE(4)_response、request对象
			
一.简介 Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象.和代表响应的response对象.request和response对象即然代表请求和响应 ...
 - 2018 CCF NOIP提高组&&普及组答案
			
答案: 这是今年的答案大家觉得能进到复赛吗? 下一篇文章将会为大家推荐我自己出的复赛题!!!
 - 使用 ss 命令查看连接信息
			
作用:打印主机socket连接信息,netstate可以做的它都可以做,比netstate 更灵活,而且由于ss使用 tcp_diag 内核模块,所以速度更快. 用法: ss [ OPTIONS ] ...
 - MySQL中常见的锁
			
一.按读写方式分类 1.读锁又称共享锁,读锁是共享的,读锁之间是互不阻塞. 2.写锁又称排他锁,写锁是排他的,写锁会阻塞其他读锁和写锁 二.按锁的粒度分类 1.表锁是MySQL中最基本的锁策略,该锁的 ...
 - Ubuntu  sudo 出现 is not in the sudoers file解决方案
			
前言: 自己想额外创建一个Linux账户,但是发现新创建的用户(lgq)并不能使用sudo指令. 但是在安装系统时创建的用户(abc)是可以正常使用的. 原因是新创建的用户并没有被赋予使用sudo指令 ...
 - mcu读写调式
			
拿仿真SPIS为例: 对于其他外设(UART.SPIM.I2S.I2C...)都是一个道理. 当MCU写时:主要对一个寄存器进行写,此寄存器是外设的入口(基本都会做并转串逻辑). spis_tx_da ...
 - 我的Python分析成长之路10
			
matplot数据可视化基础 制作提供信息的可视化(有时称作绘图)是数据分析中最重要任务之一. 1.图片(画布)与子图 plt.figure :创建一张空白的图片,可以指定图片的大小.像素. figu ...
 - mysql启动错误排查-无法申请足够内存
			
一般情况下mysql的启动错误还是很容易排查的,但是今天我们就来说一下不一般的情况.拿到一台服务器,安装完mysql后进行启动,启动错误如下: 有同学会说,哥们儿你是不是buffer pool设置太大 ...
 - leetcode刷题——双指针
			
知识点 专题-B-双指针 题目: 题解: CS-Notes Algorithm_Interview_Notes-Chinese awesome-algorithm zcy19941015的博客