当时看到这道题的时候我的脑子可能是这样的:

My left brain has nothing right, and my right brain has nothing left.

总之,看到"没有鸡你太美"这一类就直接想容斥,转化为”选出$i$个鸡你太美“

看到排列问题,直接想指数型生成函数。

设$m=\min(\frac{n}{4},a,b,c,d)$

我们使用万年不变的捆绑法,将鸡你太美当做整体考虑,即在$n-3i$个元素中选$i$个作为鸡你太美,再对其他四种进行全排列。

$$ans=\sum_{i=0}^m(-1)^i(n-4i)!\binom{n-3i}{i}\sum_{i_1\leq a-i}\sum_{i_2\leq b-i}\sum_{i_3\leq c-i}\sum_{i_4\leq d-i}\frac{1}{\prod i_j!}[\sum i_j=n-4i]$$

$$\sum_{i=0}^m(-1)^i\frac{(n-3i)!}{i!}\sum_{i_1\leq a-i}\sum_{i_2\leq b-i}\sum_{i_3\leq c-i}\sum_{i_4\leq d-i}\frac{1}{\prod i_j!}[\sum i_j=n-4i]$$

后面那一长串可以用NTT优化计算。

时间复杂度$O(n^2\log n)$,听说有直接dp的$O(n^2)$做法,但这个生成函数的做法应该是无脑多了。

 #include<bits/stdc++.h>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = << , mod = , g = , gi = ;
inline int kasumi(int a, int b){
int res = ;
while(b){
if(b & ) res = (LL) res * a % mod;
a = (LL) a * a % mod;
b >>= ;
}
return res;
}
int fac[N], inv[N];
inline void init(int n){
fac[] = ;
for(Rint i = ;i <= n;i ++) fac[i] = (LL) i * fac[i - ] % mod;
inv[n] = kasumi(fac[n], mod - );
for(Rint i = n;i;i --) inv[i - ] = (LL) inv[i] * i % mod;
}
int rev[N];
inline int calrev(int n){
int limit = , L = -;
while(limit <= n){limit <<= ; L ++;}
for(Rint i = ;i < limit;i ++) rev[i] = (rev[i >> ] >> ) | ((i & ) << L);
return limit;
}
inline void NTT(int *A, int limit, int type){
for(Rint i = ;i < limit;i ++) if(i < rev[i]) swap(A[i], A[rev[i]]);
for(Rint mid = ;mid < limit;mid <<= ){
int Wn = kasumi(type == ? g : gi, (mod - ) / (mid << ));
for(Rint j = ;j < limit;j += mid << ){
int w = ;
for(Rint k = ;k < mid;k ++, w = (LL) w * Wn % mod){
int x = A[j + k], y = (LL) w * A[j + k + mid] % mod;
A[j + k] = (x + y) % mod;
A[j + k + mid] = (x - y + mod) % mod;
}
}
}
if(type == -){
int inv = kasumi(limit, mod - );
for(Rint i = ;i < limit;i ++)
A[i] = (LL) A[i] * inv % mod;
}
}
int n, a, b, c, d, m, ans, A[N], B[N], C[N], D[N];
int main(){
scanf("%d%d%d%d%d", &n, &a, &b, &c, &d);
init(a + b + c + d);
m = min(n >> , min(min(a, b), min(c, d)));
for(Rint i = ;i <= m;i ++){
int limit = calrev(a + b + c + d - (i << ));
for(Rint j = ;j < limit;j ++){
A[j] = inv[j] * (j <= a - i);
B[j] = inv[j] * (j <= b - i);
C[j] = inv[j] * (j <= c - i);
D[j] = inv[j] * (j <= d - i);
}
NTT(A, limit, ); NTT(B, limit, ); NTT(C, limit, ); NTT(D, limit, );
for(Rint j = ;j < limit;j ++) A[j] = (LL) A[j] * B[j] % mod * C[j] % mod * D[j] % mod;
NTT(A, limit, -);
int tmp = (LL) A[n - (i << )] * fac[n - * i] % mod * inv[i] % mod;
if(i & ) ans = (ans - tmp + mod) % mod;
else ans = (ans + tmp) % mod;
}
printf("%d", ans);
}

Luogu5339

Luogu5339 [TJOI2019]唱、跳、rap和篮球 【生成函数,NTT】的更多相关文章

  1. [bzoj5510]唱跳rap和篮球

    显然答案可以理解为有(不是仅有)0对情况-1对情况+2对情况-- 考虑这个怎么计算,先计算这t对情况的位置,有c(n-3t,t)种情况(可以理解为将这4个点缩为1个,然后再从中选t个位置),然后相当于 ...

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

    [luogu5339] [TJOI2019]唱.跳.rap和篮球(容斥原理+组合数学)(不用NTT) 题面 略 分析 首先考虑容斥,求出有i堆人讨论的方案. 可以用捆绑法,把每堆4个人捆绑成一组,其他 ...

  3. 将Android手机无线连接到Ubuntu实现唱跳Rap

    您想要将Android设备连接到Ubuntu以传输文件.查看Android通知.以及从Ubuntu桌面发送短信 – 你会怎么做?将文件从手机传输到PC时不要打电话给自己:使用GSConnect就可以. ...

  4. [TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt

    [TJOI2019]唱.跳.rap和篮球 这么多人过没人写题解啊 那我就随便说说了嗷 这题第一步挺套路的,就是题目要求不能存在balabala的时候考虑正难则反,要求必须存在的方案数然后用总数减,往往 ...

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

    题目链接: [TJOI2019]唱.跳.rap和篮球 直接求不好求,我们考虑容斥,求出至少有$i$个聚集区间的方案数$ans_{i}$,那么最终答案就是$\sum\limits_{i=0}^{n}(- ...

  6. 「TJOI2019」唱、跳、rap 和篮球 题解

    题意就不用讲了吧-- 鸡你太美!!! 题意: 有 \(4\) 种喜好不同的人,分别最爱唱.跳. \(rap\).篮球,他们个数分别为 \(A,B,C,D\) ,现从他们中挑选出 \(n\) 个人并进行 ...

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

    先附一组sd图 然后放上原题链接 注意,队伍不同指的是喜好不同,不是人不同 先想到\(DP\),然后你会发现并没有什么优秀的状态设计,然后我们考虑容斥 设\(lim\)表示选的癌坤组数的上限,\(f_ ...

  8. [TJOI2019]唱,跳,rap,篮球(生成函数,组合数学,NTT)

    算是补了个万年大坑了吧. 根据 wwj 的题解(最准确),设一个方案 \(S\)(不一定合法)的鸡你太美组数为 \(w(S)\). 答案就是 \(\sum\limits_{S}[w(S)=0]\). ...

  9. [LOJ3106][TJOI2019]唱、跳、rap和篮球:DP+生成函数+NTT+容斥原理

    分析 令\(f(i)\)表示共\(i\)组同学讨论cxk的位置的方案数(不考虑其他位置上的人的爱好),这个数组可以很容易地通过依次考虑每个位置是否是四个人中最后一个人的位置来递推求解,时间复杂度\(O ...

随机推荐

  1. linux中的内核级防火墙(SELINUX)

    SElinux是基于内核开发出来的一种安全机制,被称之为内核级加强型防火墙,有力的提升了系统的安全性. SElinux的作用分为两方面:1.在服务上面加上标签: 2.在功能上面限制功能 在linux系 ...

  2. (七)springmvc之ModelAttribute注解

    一.没有使用@ModelAttribute的Controller方法. @RequestMapping("/save") public String save(User user) ...

  3. JS OOP 概述

    JS面向对象,大致内容 1.面向对象的基础 2.深入认识JS的函数 3.JS类的实现 4JS中共有成员,私有成员和静态成员 5.JS的反射 6.JS的继承 7.JS实现抽象类 8.JS事件设计模式 9 ...

  4. kong网关: service+route+upstream

    对于刚开始学习kong网关,总是一脑子浆糊迷迷糊糊.虽然已经安装好,但却不知道接下来如何下手, 因为包含项太多:service.routes.upstream.consumer.plugins等等.一 ...

  5. restTemplate源码解析(二)restTemplate的核心逻辑

    所有文章 https://www.cnblogs.com/lay2017/p/11740855.html 正文 上一篇文章中,我们构造了一个RestTemplate的Bean实例对象.本文将主要了解一 ...

  6. 借助Spring工具类如何实现支持数据嵌套的赋值操作

    假设有两个Bean A和B,想将B中的属性赋值到A实体中,可以使用get set来实现,当属性过多时,就会显得很冗余,可以使用spring提供的BeanUtils.copyProperties()来实 ...

  7. linux串口命令

    proc # cat /proc/tty/driver/serial serinfo:1.0 driver revision: 0: uart:16550A port:000003F8 irq:4 t ...

  8. Marketing Cloud contact主数据的csv导入

    使用这个mock数据生成器网站https://www.mockaroo.com/b6790790,创建一个基于Marketing Cloud contact schema的csv文件. 如果偷懒的话, ...

  9. 常用的virsh管理命令

    常用的virsh管理命令 列出所有的虚拟机 [root@ubuntu ~]# virsh list --all 显示虚拟机信息 [root@ubuntu ~]# virsh dominfo CentO ...

  10. php首页定向到内页代码

    php首页定向到内页代码,index.php头部加上以下代码, /afish-c-1/换成内页链接即可. if($_SERVER["REQUEST_URI"]=='/' || $_ ...