文章目录

  • 题目
  • 题解
  • code1(NTT)
  • code2(EGF+卷积)

题目

大中锋的学院要组织学生参观博物馆,要求学生们在博物馆中排成一队进行参观。他的同学可以分为四类:一部分最喜欢唱、一部分最喜欢跳、一部分最喜欢rap,还有一部分最喜欢篮球。如果队列中k,k+1,k+2,k+3k,k + 1,k + 2,k + 3k,k+1,k+2,k+3位置上的同学依次,最喜欢唱、最喜欢跳、最喜欢rap、最喜欢篮球,那么他们就会聚在一起讨论蔡徐坤。大中锋不希望这种事情发生,因为这会使得队伍显得很乱。大中锋想知道有多少种排队的方法,不会有学生聚在一起讨论蔡徐坤。两个学生队伍被认为是不同的,当且仅当两个队伍中至少有一个位置上的学生的喜好不同。由于合法的队伍可能会有很多种,种类数对998244353取模。

输入格式
输入数据只有一行。每行5个整数,第一个整数n,代表大中锋的学院要组织多少人去参观博物馆。接下来四个整数a、b、c、d,分别代表学生中最喜欢唱的人数、最喜欢跳的人数、最喜欢rap的人数和最喜欢篮球的人数。保证a+b+c+d≥na+b+c+d \ge na+b+c+d≥n。

输出格式
每组数据输出一个整数,代表你可以安排出多少种不同的学生队伍,使得队伍中没有学生聚在一起讨论蔡徐坤。结果对998244353998244353998244353取模。

输入输出样例
输入
4 4 3 2 1
输出
174

输入
996 208 221 132 442
输出
442572391

说明/提示
对于20%的数据,有n=a=b=c=d≤500n=a=b=c=d\le500n=a=b=c=d≤500
对于100%的数据,有n≤1000n \le 1000n≤1000 , a,b,c,d≤500a, b, c, d \le 500a,b,c,d≤500

题解

考虑枚举有iii堆人在讨论cxk小姐姐,那么被cxk迷倒的人就有4i4i4i个,且每一堆人是挨在一起的,
所以我们可以把这4i4i4i个人缩成iii个群体,每一个群体可以展开成为444人
那么现在就只用考虑剩下的n−3in-3in−3i人,放置的方案数就是Cn−3iiC_{n-3i}^iCn−3ii​
简单用整体法证明一下:
在n−3in-3in−3i人中,要选iii个拿来讨论,n−4in-4in−4i个不讨论,方案数是对应的Cn−3ii=Cn−3in−4iC_{n-3i}^i=C_{n-3i}^{n-4i}Cn−3ii​=Cn−3in−4i​
也可以理解为在n−3in-3in−3i个空格里面找iii个起点开始讨论小姐姐


接着枚举好了iii及它们可能出现的地方Cn−3iiC_{n-3i}^iCn−3ii​,我们就要去考虑剩下n−4in-4in−4i人的排列,可以乱来
(n−4i)!(n-4i)!(n−4i)!
但是attentionattentionattention,如果看了我的上一篇指数型生成函数专练,就会与这里有一点相通
题目说的方案数不同的要求是至少有一个位置上的学生的喜好不同,而不是学生本人不同
所以我们要除掉喜好篮球,跳舞,唱歌,rap本身内部的乱拍,因为从爱好上来看是看不出来排列不同的
设a,b,c,da,b,c,da,b,c,d分别代表学生中最喜欢唱的人数、最喜欢跳的人数、最喜欢rap的人数和最喜欢篮球的总人数,我们考虑的是剩下的不讨论cxk姐姐的学生乱排,所以要剪掉外层所枚举的去参与讨论的人数
(n−4i)!(a−i)!(n−i)!(c−i)!(d−i)!\frac{(n-4i)!}{(a-i)!(n-i)!(c-i)!(d-i)!}(a−i)!(n−i)!(c−i)!(d−i)!(n−4i)!​


最后写出每种喜好的生成函数,以喜欢篮球的人为例:
∑i=0cxii!\sum_{i=0}^{c}\frac{x^i}{i!}i=0∑c​i!xi​
把四种爱好卷起来,卷出最后乘积的第n−4in-4in−4i项就是我们需要除掉的东西,乘上(n−4i)!(n-4i)!(n−4i)!就是真正的乱排数


因为带取模,所以是用NTTNTTNTT跑,除的话就要变成乘逆元,所以我们可以在卷的时候就直接卷逆元

但是我们又发现虽然假设的是iii堆人在讨论,但是统计答案的时候却把≥i\ge i≥i堆人讨论的情况都统计了
而且当统计i=1i=1i=1时,会算两遍至少两堆人讨论的方案,三遍至少三堆人讨论的方案…在统计i=2i=2i=2时,会算三遍至少三堆人讨论的方案…
当统计iii的方案时,会多算CjiC_j^iCji​次至少jjj堆人讨论的方案,所以我们可以用容斥来解决


总结一下答案应该是
∑i=0min(−1)i∗Cn−3ii∗(n−4i)!(a−i)!(n−i)!(c−i)!(d−i)!\sum_{i=0}^{min}(-1)^i*C_{n-3i}^i*\frac{(n-4i)!}{(a-i)!(n-i)!(c-i)!(d-i)!}i=0∑min​(−1)i∗Cn−3ii​∗(a−i)!(n−i)!(c−i)!(d−i)!(n−4i)!​

code1(NTT)

#include <cstdio>
#include <iostream>
using namespace std;
#define mod 998244353
#define LL long long
#define MAXN 10005
int n, anum, bnum, cnum, dnum;
LL pi, ni, result;
LL a[MAXN], b[MAXN], c[MAXN], d[MAXN], rev[MAXN], fac[MAXN], Invfac[MAXN];LL qkpow ( LL x, LL y ) {LL ans = 1;while ( y ) {if ( y & 1 )ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}LL C ( int n, int m ) {return fac[n] * Invfac[m] % mod * Invfac[n - m] % mod;
}void NTT ( LL *c, LL limit, LL f ) {for ( LL i = 0;i < limit;i ++ )if ( i < rev[i] )swap ( c[i], c[rev[i]] );for ( LL i = 1;i < limit;i <<= 1 ) {LL omega = qkpow ( f == 1 ? pi : ni, ( mod - 1 ) / ( i << 1 ) );for ( LL j = 0;j < limit;j += ( i << 1 ) ) {LL w = 1;for ( LL k = 0;k < i;k ++, w = w * omega % mod ) {LL x = c[k + j], y = w * c[i + j + k] % mod;c[k + j] = ( x + y ) % mod;c[k + j + i] = ( x - y + mod ) % mod;}}}LL inv = qkpow ( limit, mod - 2 );if ( f == -1 )for ( LL i = 0;i < limit;i ++ )c[i] = c[i] * inv % mod;
}void init () {Invfac[0] = fac[0] = 1;for ( int i = 1;i <= n;i ++ )fac[i] = fac[i - 1] * i % mod;Invfac[n] = qkpow ( fac[n], mod - 2 );for ( int i = n - 1;i;i -- )Invfac[i] = Invfac[i + 1] * ( i + 1 ) % mod;
}LL solve ( int n, int A, int B, int C, int D ) {LL len = 1, l = 0;while ( len < ( ( A + B + C + D ) << 1 ) ) {len <<= 1;l ++;}for ( LL i = 0;i < len;i ++ )rev[i] = ( rev[i >> 1] >> 1 ) | ( ( i & 1 ) << ( l - 1 ) );for ( int i = 0;i < len;i ++ )a[i] = ( i <= A ? Invfac[i] : 0 );for ( int i = 0;i < len;i ++ )b[i] = ( i <= B ? Invfac[i] : 0 );for ( int i = 0;i < len;i ++ )c[i] = ( i <= C ? Invfac[i] : 0 );for ( int i = 0;i < len;i ++ )d[i] = ( i <= D ? Invfac[i] : 0 );NTT ( a, len, 1 );NTT ( b, len, 1 );NTT ( c, len, 1 );NTT ( d, len, 1 );for ( int i = 0;i < len;i ++ )a[i] = a[i] * b[i] % mod * c[i] % mod * d[i] % mod;NTT ( a, len, -1 );return a[n] * fac[n] % mod;
}int main() {pi = 3;ni = mod / pi + 1;scanf ( "%d %d %d %d %d", &n, &anum, &bnum, &cnum, &dnum );init();int k = min ( min ( min ( min ( anum, bnum ), cnum ), dnum ), n / 4 );anum -= k;bnum -= k;cnum -= k;dnum -= k;result = 0;for ( k;k >= 0;k -- ) {LL tmp = C ( n - 3 * k, k ) % mod * solve ( n - 4 * k, anum, bnum, cnum, dnum ) % mod;anum ++;bnum ++;cnum ++;dnum ++;result = ( result + ( ( k & 1 ) ? mod - tmp : tmp ) ) % mod;}printf ( "%lld\n", result );return 0;
}

code2(EGF+卷积)

#include <cstdio>
#include <iostream>
using namespace std;
#define mod 998244353
#define LL long long
#define MAXN 1005
int n, a, b, c, d;
LL result;
LL foldAB[MAXN], foldCD[MAXN], fac[MAXN], Invfac[MAXN];LL qkpow ( LL x, LL y ) {LL ans = 1;while ( y ) {if ( y & 1 )ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans;
}LL C ( int n, int m ) {return fac[n] * Invfac[m] % mod * Invfac[n - m] % mod;
}void Fac () {Invfac[0] = fac[0] = 1;for ( int i = 1;i <= n;i ++ )fac[i] = fac[i - 1] * i % mod;Invfac[n] = qkpow ( fac[n], mod - 2 );for ( int i = n - 1;i;i -- )Invfac[i] = Invfac[i + 1] * ( i + 1 ) % mod;
}int main() {scanf ( "%d %d %d %d %d", &n, &a, &b, &c, &d );Fac();int k = min ( min ( min ( min ( a, b ), c ), d), n / 4 );a -= k;b -= k;c -= k;d -= k;for ( int i = 0;i <= a;i ++ )for ( int j = 0;j <= b;j ++ )foldAB[i + j] = ( foldAB[i + j] + Invfac[i] * Invfac[j] % mod ) % mod;for ( int i = 0;i <= c;i ++ )for ( int j = 0;j <= d;j ++ )foldCD[i + j] = ( foldCD[i + j] + Invfac[i] * Invfac[j] % mod ) % mod;result = 0;for ( k;k >= 0;k -- ) {LL ans = 0;int tp = n - 4 * k;for ( int i = 0;i <= tp;i ++ )ans = ( ans + foldAB[i] * foldCD[tp - i] % mod ) % mod;ans = ans * fac[tp] % mod * C ( n - k * 3, k ) % mod;result = ( result + ( ( k & 1 ) ? mod - ans : ans ) ) % mod;a ++;b ++;c ++;d ++;for ( int i = 0;i <= a;i ++ )foldAB[i + b] = ( foldAB[i + b] + Invfac[i] * Invfac[b] % mod ) % mod;for ( int i = 0;i <= b;i ++ )foldAB[i + a] = ( foldAB[i + a] + Invfac[i] * Invfac[a] % mod ) % mod;foldAB[a + b] = ( foldAB[a + b] - Invfac[a] * Invfac[b] % mod + mod ) % mod;for ( int i = 0;i <= c;i ++ )foldCD[i + d] = ( foldCD[i + d] + Invfac[i] * Invfac[d] % mod ) % mod;for ( int i = 0;i <= d;i ++ )foldCD[i + c] = ( foldCD[i + c] + Invfac[i] * Invfac[c] % mod ) % mod;foldCD[c + d] = ( foldCD[c + d] - Invfac[c] * Invfac[d] % mod ) % mod;}printf ( "%lld\n", result );return 0;
}

代码或者思路有任何问题欢迎评论

[TJOI2019]唱、跳、rap和篮球(指数型生成函数+NTT+卷积)相关推荐

  1. 一个摄像头就能让虚拟人唱跳rap,抖音即可玩

    允中 发自 凹非寺 量子位 | 公众号 QbitAI 全身动作捕捉,现在无需昂贵的动捕设备,只要一个摄像头就能轻松实现. 并且就在抖音上,人人都能上手体验. 上面这段虚拟数字形象跳舞的视频采用了抖音直 ...

  2. 3D模型学会了「唱、跳、Rap、篮球」,程序员们全沉迷「鸡你太美」

    继 B 站之后,GitHub 网友也开始沉迷「鸡你太美」,让 3D 姿态也学会了「唱.跳.Rap.篮球」,而且动作准确度和连贯性似乎一点也不输练习时长两年半的练习生. 看了这段 demo 之后,网友戏 ...

  3. 我写小程序像菜虚鲲——1、唱,跳,rap,篮球

    引言 大家好,我是练习时长两年半的个人练习生菜虚鲲,我喜欢唱,跳,rap,篮球,Music! 为了避免律师含,就不po鲲鲲的原图咯~ 在小作坊待久了,都忘记自己的本职工作当初进来是一枚Android开 ...

  4. 2019 ACM - ICPC 上海网络赛 E. Counting Sequences II (指数型生成函数)

    繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量题解和代码,题目难度不一定按照题号排序,我会在每道题后面加上题目难度指数(1∼51 \sim 51∼5),以模板题难度 11 ...

  5. 指数型生成函数[bzoj3456]城市规划

    前言 打完多项式板子后的第一题+清真的题意 题目相关 题目链接 题目大意 求nnn个点的简单(无重边无自环)无向连通图数目 输出模1004535809(479∗221+1)1004535809(479 ...

  6. 指数型生成函数(EGF)略解

    因为我菜,所以我只能把重点的写一手. 学习了这篇文章 首先,生成函数是来简化运算.方便表达的. e x = ∑ i = 0 ∞ x i i ! e^x=\sum_{i=0}^{\infty}\frac ...

  7. 练习时长两年半,二本学历,没背景,会唱跳篮球,美团四面成功拿下offer

    个人背景 又逢"金九银十",年轻的毕业生们满怀希望与忐忑,去寻找.竞争一个工作机会.已经在职的开发同学,也想通过社会招聘或者内推的时机争取到更好的待遇.更大的平台. 然而,面试人群 ...

  8. P2012 拯救世界2(指数型生成函数)

    P2012 拯救世界2 三种基因,我们分别列出其生成函数: F(x)=∑n≥0xnn!=exG(x)=∑n≥0x2n+1(2n+1)!=12(∑n≥0xnn!−∑n≥0(−1)nxnn!)=12(ex ...

  9. 【集训队作业2018】复读机【指数型生成函数】【单位根反演】【二项式定理】

    传送门 单位根反演听着高级,其实没啥技术含量-- 本文是篇几乎没有证明的佛系讲解 单位根反演的式子长这样: 1n∑i=0n−1ωnik=[k∣n]\frac{1}{n}\sum_{i=0}^{n-1} ...

最新文章

  1. [转]在ITunes播放中前进、后退五秒的快捷键
  2. why Material request downlaod get an empty BDOC in SMW01 - structure MGV_TLMNR
  3. C# WPF MVVM模式下在主窗体显示子窗体并获取结果
  4. 计算机的使用编码,计算机中使用的编码
  5. 交互设计-手机端原型尺寸规范
  6. 新手前端微信小程序img图片无法显示问题
  7. 山西民生云认证工资_山西民生云养老资格认证手机版-山西民生云社会保险综合服务平台v2.2 最新版-007游戏网...
  8. python numpy 多条件筛选
  9. 输入子系统代码内核代码分析
  10. excel使用正则表达式
  11. VS2017编译在XP环境下运行的程序
  12. ROS机器人高效编程(原书第3版)勘误、问题及资料汇总
  13. Nginx从入门到应用-姜威-专题视频课程
  14. 小孩学计算机的电视剧,小时候在教育频道看的一个电视剧,好像是叮当演的,讲一堆小孩学唱戏之类的...
  15. 7-3 学习打卡(12.19)
  16. 快速了解 Java 9 - 16 新特性,助你脱离内卷
  17. 5G/NR 学习笔记: 基本问答 RACH PRACH
  18. 第九届“图灵杯”NEUQ-ACM程序设计竞赛个人赛前十题(能力有限)
  19. JS刷新页面的几种类型
  20. Android——仿京东淘宝分类页面

热门文章

  1. Python资料分享来袭,收下不谢!
  2. 嵌套饼图_旭日图的效率,高到饼图都羡慕
  3. 12如何隐藏dock栏_iPhone边框“变色”壁纸,隐藏Dock栏
  4. 客制化键盘编程_指尖运动会,谁是打字冠军,双十一机械键盘推荐
  5. 《笨办法学python》6_笨办法学Python 习题 25: 更多更多的练习
  6. _云计算学习路线图素材课件,Linux中软件安装的方式
  7. php 设置excel格式,php 操作excel文件的方法小结
  8. 历史版本_新版本爆料第弹丨英雄练习新去处,荣耀历史秀出来!
  9. 7-3 符号三角形 (10 分)(思路+详解)
  10. 10-4 5-4 查询至少生产三种不同速度PC的厂商 (20 分)