题目链接

题目分析

据说这是一道生成函数题

看到限制条件,我们首先想到的就是对有多少组讨论cxk的人进行容斥。然后就是求剩下的人随便放有多少种方法了。考虑现在每种剩\(a,b,c,d\)人,还需要排\(n\)人,那么方案数就是

\[\sum_{i=1}^a\sum_{j=1}^b\sum_{k=1}^c\sum_{l=1}^d [i+j+k+l=n]{n\choose i}{n - i\choose j}{n-i-j\choose k}{n-i-j-k\choose l}
\]

其中\([]\)内表达式为真时,值为\(1\),否则为\(0\)。

可以化简为

\[\sum_{i=1}^a\sum_{j=1}^b\sum_{k=1}^c[0\leqslant n-i-j-k\leqslant d]{n\choose i}{n-i\choose j}{n-i-j \choose k}
\]

这个式子暴力求得话复杂度明显不对,他是\(O(n^3)\)的。

考虑只枚举\(i\)和\(j\)。那么满足\(0\leqslant n-i-j-k\leqslant d\)的\(k\)显然是一个连续的区间,不妨记作\([L,R]\)。那么对答案的贡献就是

\[{n\choose i}{n-i\choose j}\sum_{k=L}^R{n-i-j\choose k}
\]

后面那个求和预处理加前缀和即可\(O(1)\)求得。那么时间复杂度就降到了\(O(n^2)\)。加上外面一层容斥,那么总时间复杂度就是\(O(n^3)\)。

实现的时候注意边界条件!!!

参考程序

码风氪化

  1. #include <bits/stdc++.h>
  2. #define LL long long
  3. using namespace std;
  4. const LL Maxn = 1010;
  5. const LL Maxa = 510;
  6. const LL Mod = 998244353;
  7. LL N, A[ 4 ], Fact[ Maxn ], Inv[ Maxn ], C[ Maxn ][ Maxn ], Sum[ Maxn ][ Maxn ], Ans;
  8. void Exgcd( LL a, LL b, LL &x, LL &y ) { if( b == 0 ) { x = 1; y = 0; return; } Exgcd( b, a % b, y, x ); y -= a / b * x; return; }
  9. LL inv( LL a ) { LL x, y; Exgcd( a, Mod, x, y ); if( x < 0 ) x += Mod; return x; }
  10. LL S( LL n, LL l, LL r ) { LL Ans = Sum[ n ][ r ]; if( l ) Ans = ( Ans - Sum[ n ][ l - 1 ] + Mod ) % Mod; return Ans; }
  11. LL Cal( LL Sta ) {
  12. LL Ans = 0; for( LL i = 0; i < 4; ++i ) A[ i ] -= Sta;
  13. for( LL i = 0; i <= A[ 0 ] && i <= N - Sta * 4; ++i )
  14. for( LL j = max( 0LL, N - Sta * 4 - A[ 2 ] - A[ 3 ] - i ); j <= A[ 1 ] && i + j <= N - Sta * 4; ++j ) {
  15. Ans = ( Ans + C[ N - Sta * 4 ][ i ] * C[ N - Sta * 4 - i ][ j ] % Mod * S( N - Sta * 4 - i - j, max( 0LL, N - Sta * 4 - i - j - A[ 3 ] ), min( N - Sta * 4 - i - j, A[ 2 ] ) ) % Mod ) % Mod;
  16. }
  17. for( LL i = 0; i < 4; ++i ) A[ i ] += Sta; return Ans;
  18. }
  19. void Work() {
  20. for( LL i = 0; i <= N / 4; ++i ) {
  21. for( LL j = 0; j < 4; ++j ) if( i > A[ j ] ) return;
  22. if( i & 1 ) Ans = ( Ans - C[ N - i * 3 ][ i ] * Cal( i ) % Mod + Mod ) % Mod;
  23. else Ans = ( Ans + C[ N - i * 3 ][ i ] * Cal( i ) % Mod ) % Mod;
  24. }
  25. return;
  26. }
  27. int main() {
  28. scanf( "%lld", &N ); for( LL i = 0; i < 4; ++i ) scanf( "%lld", &A[ i ] );
  29. Fact[ 0 ] = 1; for( LL i = 1; i <= N; ++i ) Fact[ i ] = Fact[ i - 1 ] * i % Mod;
  30. Inv[ N ] = inv( Fact[ N ] ); for( LL i = N - 1; i >= 0; --i ) Inv[ i ] = Inv[ i + 1 ] * ( i + 1 ) % Mod;
  31. for( LL i = 0; i <= N; ++i ) for( LL j = 0; j <= i; ++j ) C[ i ][ j ] = Fact[ i ] * Inv[ j ] % Mod * Inv[ i - j ] % Mod;
  32. for( LL i = 0; i <= N; ++i ) for( LL j = 0; j <= i; ++j ) Sum[ i ][ j ] = ( Sum[ i ][ j - 1 ] + C[ i ][ j ] ) % Mod;
  33. Work(); printf( "%lld\n", Ans );
  34. return 0;
  35. }

「TJOI2019」唱、跳、rap 和篮球的更多相关文章

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

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

  2. [bzoj5510]唱跳rap和篮球

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

  3. 【LOJ】#3109. 「TJOI2019」甲苯先生的线段树

    LOJ#3109. 「TJOI2019」甲苯先生的线段树 发现如果枚举路径两边的长度的话,如果根节点的值是$x$,左边走了$l$,右边走了$r$ 肯定答案会是$(2^{l + 1} + 2^{r + ...

  4. LG5337/BZOJ5508 「TJOI2019」甲苯先生的字符串 线性动态规划+矩阵加速

    问题描述 LG5337 BZOJ5508 题解 设\(opt_{i,j}(i \in [1,n],j \in [1,26])\)代表区间\([1,i]\),结尾为\(j\)的写法. 设\(exist_ ...

  5. LG5338/BZOJ5509/LOJ3105 「TJOI2019」甲苯先生的滚榜 Treap

    问题描述 LG5338 LOJ3105 BZOJ5509 题解 建立一棵\(\mathrm{Treap}\),把原来的\(val\)换成两个值\(ac,tim\) 原来的比较\(val_a<va ...

  6. LOJ#3104「TJOI2019」甲苯先生的字符串

    题目描述 一天小甲苯得到了一条神的指示,他要把神的指示写下来,但是又不能泄露天机,所以他要用一种方法把神的指示记下来. 神的指示是一个字符串,记为字符串 \(s_1\),\(s_1\) 仅包含小写字母 ...

  7. 「TJOI2019」大中锋的游乐场

    题目链接 问题分析 比较明显的最短路模型.需要堆优化的dij.建图的时候注意细节就好. 参考程序 #include <bits/stdc++.h> #define LL long long ...

  8. 「TJOI2019」甲苯先生的滚榜

    题目链接 问题分析 参照数据范围,我们需要一个能够在\(O(n\log n)\)复杂度内维护有序数列的数据结构.那么平衡树是很好的选择.参考程序中使用带旋Treap. 参考程序 #pragma GCC ...

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

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

随机推荐

  1. springmvc的MultipartFile参数如果不上传文件报错的问题

    @RequestMapping(value = "/updateInformation",method = RequestMethod.POST) @ResponseBody pu ...

  2. Maven下载安装测试

    一.Maven下载 在Maven官网下载压缩包 二.安装 解压后目录如下 bin目录包含mvn的运行脚本 boot目录包含一个类加载器的框架,加载自己的类库 conf是配置文件目录 lib目录包含一些 ...

  3. 【深入理解JVM】类加载器与双亲委派模型 (转)

    出处: [深入理解JVM]类加载器与双亲委派模型 加载类的开放性 类加载器(ClassLoader)是Java语言的一项创新,也是Java流行的一个重要原因.在类加载的第一阶段“加载”过程中,需要通过 ...

  4. Dubbo架构

    原文链接http://dubbo.apache.org 架构图 节点角色说明 节点 角色说明 Provider 暴露服务的服务提供方 Consumer 调用远程服务的服务消费方 Registry 服务 ...

  5. Java排序--排序算法(内排序)

    常用内排序算法 我们通常所说的排序算法往往指的是内部排序算法,即需要排序的数据在计算机内存中完成整个排序的过程,当数据率超大或排序较为繁琐时常借助于计算机的硬盘对大数据进行排序工作,称之为外部排序算法 ...

  6. 导出excel-文件流

    后台代码(控制器或者dao层) public void Excel(){ //第一步:(1)以虚拟表的形式获取导出数据 DataTable dt_0 = this.service.Excel(); / ...

  7. Linux小知识:rm -rf/*会将系统全部删除吗

    Linux小知识:rm -rf/*会将系统全部删除吗 本文是学习笔记,视频地址为:https://www.bilibili.com/video/av62839850 执行上面的命令并不会删除所有内容( ...

  8. python CGI环境搭建

    本文web服务器使用的为apache. 1. 安装apache yum install -y httpd 2. 配置apache 修改apache配置文件/etc/httpd/conf/httpd.c ...

  9. python学习-输入输出

    Python的输入和输出非常方便,下面详细记录一下 任何计算机程序都是为了执行一个特定的任务,有了输入,用户才能告诉计算机程序所需的信息,有了输出,程序运行后才能告诉用户任务的结果.输入是Input, ...

  10. 完美解决Mysql的Access denied for user 'root'@'%的'问题

    背景:mysql5.6 root已授权所有数据库,执行过下面的语句 grant all privileges on *.* to 'root'@'%' identified by 'root' 当使用 ...