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

文章目录

  • 题目
  • 题解
  • 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+dn

输出格式
每组数据输出一个整数,代表你可以安排出多少种不同的学生队伍,使得队伍中没有学生聚在一起讨论蔡徐坤。结果对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=d500
对于100%的数据,有n≤1000n \le 1000n1000a,b,c,d≤500a, b, c, d \le 500a,b,c,d500

题解

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


接着枚举好了iii及它们可能出现的地方Cn−3iiC_{n-3i}^iCn3ii,我们就要去考虑剩下n−4in-4in4i人的排列,可以乱来
(n−4i)!(n-4i)!(n4i)!
但是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)!}(ai)!(ni)!(ci)!(di)!(n4i)!


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


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

但是我们又发现虽然假设的是iii堆人在讨论,但是统计答案的时候却把≥i\ge ii堆人讨论的情况都统计了
而且当统计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=0min(1)iCn3ii(ai)!(ni)!(ci)!(di)!(n4i)!
在这里插入图片描述

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;
} 

代码或者思路有任何问题欢迎评论
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Sum of Paths CodeForces - 1467D

Sum of Paths CodeForces - 1467D Tagscombinatorics dp math *2200 题意&#xff1a; 定义一条好的路径&#xff0c;当且仅当从任意点出发之后恰好经过了 k 次移动&#xff0c;定义这条路径的权值为经过点权值的总和(可重)&#xff0c;进行 q 次修改&#xff0c;每次将ak 改…

[矩阵乘法/快速幂专题]Arc of Dream,Recursive sequence,233 Matrix,Training little cats

矩阵快速幂习题复习矩阵乘法及快速幂模板乘法模板快速幂模板T1&#xff1a;Arc of Dream题目题解codeT2&#xff1a;Recursive sequence题目题解codeT3&#xff1a;233 Matrix题目题解codeT4&#xff1a;Training little cats题目题解code做题的时候后悔没有保存过模板&#xf…

你准备好了在云中工作吗?

前几天写了一篇文章 《云时代的.NET》&#xff0c;今天继续这个话题聊下云时代的技能。无服务器计算&#xff0c;容器化&#xff0c;云原生应用&#xff0c;DevOps&#xff0c;人工智能&#xff0c;机器学习以及混合云和多云解决方案等IT趋势正在成为主流或“新常态”。所有大小…

最长公共上升子序列(LCIS)

题意&#xff1a; 求最长公共上升子序列 题解&#xff1a; 最长公共上升子序列 最长公共子序列&#xff08;LCS&#xff09;与最长上升子序列&#xff08;LIS&#xff09; LCS核心代码&#xff1a; for(int i1;i<n;i){for(int j1;j<m;j){if(a[i]b[j])dp[i][j]max(dp[…

[高斯消元及理论]线性方程组整数/浮点数,模线性方程组,异或方程组模板

文章目录理论线性方程组整数类型解线性方程组浮点类型解模线性方程组异或方程组高斯约旦消元约旦消元无解无穷解唯一解理论 高斯消元法&#xff0c;是线性代数规划中的一个算法&#xff0c;可用来为线性方程组求解。但其算法十分复杂&#xff0c;不常用于加减消元法&#xff0c…

eShopOnContainers 知多少[7]:Basket microservice

引言Basket microservice&#xff08;购物车微服务&#xff09;主要用于处理购物车的业务逻辑&#xff0c;包括&#xff1a;购物车商品的CRUD订阅商品价格更新事件&#xff0c;进行购物车商品同步处理购物车结算事件发布订阅订单成功创建事件&#xff0c;进行购物车的清空操作架…

后缀数组 SA

后缀数组 SA 后缀树组(SA&#xff0c;suffix array)&#xff0c;用于处理字符串子串形成的结构。 处理子串的结构主要方式有&#xff1a;后缀数组 SA&#xff0c;后缀自动机 SAM&#xff0c;后缀树 ST。 后缀树和后缀自动机暂时决定咕咕咕&#xff0c;以后学习可以参考ix35 的字…

微软热门开源项目及代码库地址

点击蓝字关注我这几年来&#xff0c;微软在开源与社区方向的努力与成就是全世界有目共睹的。微软的开源项目超过2000多个&#xff0c;挑了一些比较火热的给大家整理了一下。欢迎补充~Visual Studio Code非常流行的跨平台代码编辑器&#xff0c;提供全面的编辑和调试支持、可扩展…

[树链剖分][SDOI 2011]染色,Housewife Wind

文章目录T1&#xff1a;Housewife Wind题目题解codeT2&#xff1a;染色题目题解code今天选择写这篇博客主要是为了告诉大家一个道理&#xff0c;数组比vectorvectorvector快太多了&#xff0c;我这两道题第一次都因为vectorvectorvector&#xff0c;TTT到飞起 T1&#xff1a;…

ASP.NET Core 网站运行时修改设置如何自动生效

点击蓝字关注我在ASP.NET Core中&#xff0c;如果修改了appsettings.json中的设置&#xff0c;那么默认情况下就得重启网站才能生效。有没有办法在修改设置后自动刷新并应用呢&#xff1f;背景首先&#xff0c;我们看看默认模板建出来的 ASP.NET Core 网站&#xff0c;配置文件…

1022. 宠物小精灵之收服

1022. 宠物小精灵之收服 题意&#xff1a; 现在有n个胶囊&#xff0c;m个生命值&#xff0c;k个怪物&#xff0c;每个怪物需要a[i]个胶囊&#xff0c;且会造成b[i]个伤害后才能捕获&#xff0c;问在活着的前提下&#xff0c;最多捕获多少怪物&#xff0c;在怪物最多的情况下剩…

【周末狂欢赛6】[AT1219]历史研究(回滚莫队),大魔法师(矩阵+线段树),单峰排列

文章目录T1&#xff1a;单峰排列题目题解codeT2&#xff1a;历史研究题目题解codeT3&#xff1a;大魔法师题目题解code我可能这辈子都更不出来狂欢赛5了&#xff0c;先咕咕 T1&#xff1a;单峰排列 题目 一个n的全排列A[i]是单峰的&#xff0c;当且仅当存在某个x使得A[1]<…

YBTOJ:圈套问题(分治法、鸽笼原理)

文章目录题目描述数据范围解析代码图片转载自&#xff1a; https://blog.csdn.net/weixin_43346722/article/details/118435430题目描述 平面上有 n个点&#xff0c;用n个大小相同的圆分别将一个点作为圆心&#xff0c;同时满足圆圈不相交&#xff0c;求圆的最大半径。 数据范…

ASP.NET Core 实战:使用 NLog 将日志信息记录到 MongoDB

一、前言在项目开发中&#xff0c;日志系统是系统的一个重要组成模块&#xff0c;通过在程序中记录运行日志、错误日志&#xff0c;可以让我们对于系统的运行情况做到很好的掌控。同时&#xff0c;收集日志不仅仅可以用于诊断排查错误&#xff0c;由于日志同样也是大量的数据&a…

[学习笔记] 伸展树splay详解+全套模板+例题[Luogu P3369 【模板】普通平衡树]

文章目录引入概念全套模板变量声明updaterotate旋转splay操作insert插入delete删除查找x的位置查找第k大前驱/后继极小值-inf和极大值inf的作用例题&#xff1a;P3369 【模板】普通平衡树题目code声明一下&#xff0c;许多代码的注解都在模板代码里面写了的&#xff0c;所以正文…

手写AspNetCore 认证授权代码

在普通的MVC项目中 我们普遍的使用Cookie来作为认证授权方式&#xff0c;使用简单。登录成功后将用户信息写入Cookie&#xff1b;但当我们做WebApi的时候显然Cookie这种方式就有点不适用了。在dotnet core 中 WebApi中目前比较流行的认证授权方式是Jwt (Json Web Token) 技术。…

YBTOJ:采矿战略(线段树维护dp、树链剖分)

文章目录题目描述解析代码题目描述 所谓线段树维护dp&#xff0c;就是在线段树上维护dp &#xff08;逃&#xff09; 解析 把树剖一下后就变成了区间问题 考虑建一棵线段树&#xff0c;每一个结点都是一个背包 这样就能区间查询&#xff0c;也能带修了 这种做法复杂度其实并不…

【用皇宫三十六计生存法则带你走进LCT(动态树)】LCT概念+模板+例题【洛谷P3690 Link Cut Tree(动态树)】

文章目录LCT概念模板rotatoisrootsplayaccessmakerootsplitfindrootlinkcut封装版例题题目code普通版code封装版这篇博客主要是帮助大家理解各个模板及LCTLCTLCT的意思&#xff0c;方便理解&#xff0c;模板写法的理解在代码里有注释详解&#xff0c;如果要看原理的话&#xff…

迈向现代化的 .Net 配置指北

1. 欢呼 .NET Standard 时代我现在已不大提 .Net Core&#xff0c;对于我来说&#xff0c;未来的开发将是基于 .NET Standard&#xff0c;不仅仅是 面向未来 &#xff0c;也是 面向过去&#xff1b;不只是 .Net Core 可以享受便利&#xff0c; .NET Framework 不升级一样能享受…

YBTOJ洛谷P2042:维护数列(平衡树)

文章目录题目描述解析删除区间插入数列修改&翻转区间和&最大子段和代码传送门题目描述 解析 阴间题… 这不是裸的板子吗&#xff1f; 国赛真的有人能把这题写出来吗… 应该算一道练习作用很强的题了 写完这题&#xff0c;各种平衡树维护区间操作的方法可以说是毕业了吧…