[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)!\)就好啦。

贴个代码

  1. #include <bits/stdc++.h>
  2. #define N 1010
  3. using namespace std;
  4. typedef long long ll;
  5. const int mod = 998244353 ;
  6. int C[N][N],num[5],len[5],fac[N<<2],inv[N<<2],b[5][N<<2];
  7. int n;
  8. char *p1,*p2,buf[100000];
  9. #define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
  10. 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;}
  11. int qpow(int x,int y)
  12. {
  13. int ans=1;
  14. while(y)
  15. {
  16. if(y&1) ans=(ll)ans*x%mod;
  17. y>>=1;
  18. x=(ll)x*x%mod;
  19. }
  20. return ans;
  21. }
  22. void init()
  23. {
  24. fac[0]=1; for(int i=1;i<=1000;i++) fac[i]=(ll)fac[i-1]*i%mod;
  25. inv[0]=1; for(int i=1;i<=1000;i++) inv[i]=qpow(fac[i],mod-2);
  26. }
  27. void ntt(int *a,int len,int flg)
  28. {
  29. int i,j,k,t,w,x,tmp;
  30. for(i=k=0;i<len;i++)
  31. {
  32. if(i>k) swap(a[i],a[k]);
  33. for(j=len>>1;(k^=j)<j;j>>=1);
  34. }
  35. for(k=2;k<=len;k<<=1)
  36. {
  37. t=k>>1;
  38. x=qpow(3,(mod-1)/k);
  39. if(flg==-1) x=qpow(x,mod-2);
  40. for(i=0;i<len;i+=k)
  41. for(j=i,w=1;j<i+t;j++)
  42. {
  43. tmp=(ll)a[j+t]*w%mod;
  44. a[j+t]=(a[j]-tmp+mod)%mod;
  45. a[j]=(a[j]+tmp)%mod;
  46. w=(ll)w*x%mod;
  47. }
  48. }
  49. if(flg==-1) for(t=qpow(len,mod-2),i=0;i<len;i++) a[i]=(ll)a[i]*t%mod;
  50. }
  51. int calc(int k)
  52. {
  53. int l=1;
  54. while(l<=max((num[4]-k)<<1,(n-4*k)<<1)) l<<=1;
  55. while(l<=(num[4]<<2)) l<<=1;
  56. for(int i=1;i<=4;i++)
  57. {
  58. len[i]=num[i]-k;
  59. for(int j=0;j<=l;j++) b[i][j]=0;
  60. }
  61. for(int i=1;i<=4;i++) for(int j=0;j<=len[i];j++) b[i][j]=inv[j];
  62. for(int i=1;i<=4;i++) ntt(b[i],l,1);
  63. 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;
  64. ntt(b[1],l,-1);
  65. return (ll)b[1][n-4*k]*fac[n-4*k]%mod;
  66. }
  67. int main()
  68. {
  69. n=rd(); for(int i=1;i<=4;i++) num[i]=rd();
  70. for(int i=0;i<=n;i++)
  71. {
  72. C[i][0]=1;
  73. for(int j=1;j<=i;j++) C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
  74. }
  75. sort(num+1,num+5);
  76. int l=1;
  77. while(l<=(num[4]<<2)) l<<=1;
  78. init();
  79. int ans=0;
  80. for(int i=0;(i<<2)<=min(n,num[1]<<2);i++)
  81. {
  82. int mdl=(ll)calc(i)*C[n-3*i][i]%mod;
  83. if(i&1) (ans-=mdl)%=mod;
  84. else (ans+=mdl)%=mod;
  85. }
  86. printf("%d\n",(ans+mod)%mod);
  87. return 0;
  88. }

[TJOI2019]唱、跳、rap和篮球_生成函数_容斥原理_ntt的更多相关文章

  1. [bzoj5510]唱跳rap和篮球

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

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

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

  3. Luogu5339 [TJOI2019]唱、跳、rap和篮球 【生成函数,NTT】

    当时看到这道题的时候我的脑子可能是这样的: My left brain has nothing right, and my right brain has nothing left. 总之,看到&qu ...

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

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

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

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

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

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

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

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

  8. Oracle学习总结_day03_day04_条件查询_排序_函数_子查询

    本文为博主辛苦总结,希望自己以后返回来看的时候理解更深刻,也希望可以起到帮助初学者的作用. 转载请注明 出自 : luogg的博客园 谢谢配合! day03_条件查询_排序_函数 清空回收站: PUR ...

  9. 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 ...

随机推荐

  1. Django-C002-深入模型,到底有多深

    此文章完成度[100%]留着以后忘记的回顾.多写多练多思考,我会努力写出有意思的demo,如果知识点有错误.误导,欢迎大家在评论处写下你的感想或者纠错. ORM介绍:对象关系映射(英语:(Object ...

  2. Ckeditor for Drupal

      Ckeditor for Drupal   关于Drupal的所见即所得编辑器,Ckeditor是一个不错的选择,而且可以在Ckeditor官网直接下载到专为Drupal制作的版本: http:/ ...

  3. ios之ARC

    本文部分实例取自iOS 5 Toturail一书中关于ARC的教程和公开内容,仅用于技术交流和讨论.请不要将本文的部分或全部内容用于商用,谢谢合作. 欢迎转载本文,但是转载请注明本文出处:http:/ ...

  4. 分享一个C++与Python开发的中小型通用游戏服务端框架(跨平台,开源,适合MMORPG游戏)

    在开发一款游戏项目时,在立项时我们往往会考虑或者纠结很多,比如: 1,对于开发来说:服务端和客户端应该选择什么语言?用什么协议通信才更效率?协议后期如何维护?Socket是用长连接还是短连接?TCP还 ...

  5. Linux基础学习-chrony时间同步服务

    Chrony时间同步 NTP(Network Time Protocol,网络时间协议)是用来使网络中的各个计算机时间同步的一种协议.它的用于是把计算机的时钟同步到世界协调时UTC,其精度在局域网内可 ...

  6. GIMP素描效果

    1/打开图片,拖动图片到GIMP软件 2/复制两次图层 3/选中最上面的一个图层,mode改为Dodge 4/点击Color,选择Invert,可以看到图片变淡了 5/点击Filters,Distor ...

  7. heartbeat+drdb+nfs实现高可用

    一.环境 nfsserver01:192.168.127.101 心跳:192.168.42.101 centos7.3 nfsserver02:192.168.127.102 心跳:192.168. ...

  8. 分享读C Primer Plus时遇到的一个问题(补档5月7日)

    最近在学习C Primer Plus.书中第66页,3.8 关键概念 这一小节中有这一段话: “计算机中的浮点数和整数在本质上不同,其存储方式和运算过程有很大区别.即使两个 32 位存储单元存储的位组 ...

  9. c++ 快速幂 代码实现

    懒得打代码系列… 不过这个代码挺短的死背下来也ok 解析在最下面 建议自己手动试个数据理解一下 比如 3^5 ^^ 原理:a ^ b = a ^ (b / 2) * 2 (b是奇数的话还要再乘一个a) ...

  10. 工作中的Python脚本

    本章内容 1.rawlog处理   2.域名item接口刷新 3.备案结果查询 4.多级域名中取主域 5.发送邮件 6.通过api获取cdn edge ip 7.多线程下载 1.rawlog处理 脚本 ...