题目链接

CF960G

题解

FJOI2016只不过数据范围变大了

考虑如何预处理第一类斯特林数

性质

\[x^{\overline{n}} = \sum\limits_{i = 0}^{n}\begin{bmatrix} n \\ i \end{bmatrix}x^{i}
\]

分治\(NTT\)即可在\(O(nlog^2n)\)的时间内预处理出同一个\(n\)的所有\(\begin{bmatrix} n \\ i \end{bmatrix}\)

其实还有比较优美的倍增\(fft\)的\(O(nlogn)\)的方法

  1. #include<algorithm>
  2. #include<iostream>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<vector>
  7. #include<queue>
  8. #include<cmath>
  9. #include<map>
  10. #define LL long long int
  11. #define REP(i,n) for (int i = 1; i <= (n); i++)
  12. #define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
  13. #define cls(s,v) memset(s,v,sizeof(s))
  14. #define mp(a,b) make_pair<int,int>(a,b)
  15. #define cp pair<int,int>
  16. using namespace std;
  17. const int maxn = 400005,maxm = 100005,INF = 0x3f3f3f3f;
  18. inline int read(){
  19. int out = 0,flag = 1; char c = getchar();
  20. while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
  21. while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
  22. return flag ? out : -out;
  23. }
  24. const int P = 998244353,G = 3;
  25. inline int qpow(int a,int b){
  26. int re = 1;
  27. for (; b; b >>= 1,a = 1ll * a * a % P)
  28. if (b & 1) re = 1ll * re * a % P;
  29. return re;
  30. }
  31. int R[maxn];
  32. void NTT(int* a,int n,int f){
  33. for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i],a[R[i]]);
  34. for (int i = 1; i < n; i <<= 1){
  35. int gn = qpow(G,(P - 1) / (i << 1));
  36. for (int j = 0; j < n; j += (i << 1)){
  37. int g = 1,x,y;
  38. for (int k = 0; k < i; k++,g = 1ll * g * gn % P){
  39. x = a[j + k],y = 1ll * a[j + k + i] * g % P;
  40. a[j + k] = (x + y) % P,a[j + k + i] = (P - y + x) % P;
  41. }
  42. }
  43. }
  44. if (f == 1) return;
  45. int nv = qpow(n,P - 2); reverse(a + 1,a + n);
  46. for (int i = 0; i < n; i++) a[i] = 1ll * a[i] * nv % P;
  47. }
  48. int n,a,b,A[20][maxn],deg[20],cnt;
  49. void solve(int l,int r){
  50. if (l == r){
  51. cnt++; A[cnt][0] = l; A[cnt][1] = 1; deg[cnt] = 1;
  52. return;
  53. }
  54. int mid = l + r >> 1;
  55. solve(l,mid); solve(mid + 1,r);
  56. int a = cnt - 1,b = cnt,n = 1,L = 0;
  57. while (n <= deg[a] + deg[b]) n <<= 1,L++;
  58. for (int i = 1; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
  59. for (int i = deg[a] + 1; i < n; i++) A[a][i] = 0;
  60. for (int i = deg[b] + 1; i < n; i++) A[b][i] = 0;
  61. NTT(A[a],n,1); NTT(A[b],n,1);
  62. for (int i = 0; i < n; i++) A[a][i] = 1ll * A[a][i] * A[b][i] % P;
  63. NTT(A[a],n,-1);
  64. cnt--;
  65. deg[a] += deg[b];
  66. }
  67. int C(int n,int m){
  68. if (n < m) return 0;
  69. int re = 1;
  70. for (int i = 1; i <= m; i++)
  71. re = 1ll * re * (n - i + 1) % P * qpow(i,P - 2) % P;
  72. return re;
  73. }
  74. int S[100][100];
  75. int main(){
  76. n = read(); a = read(); b = read();
  77. if (a + b - 2 > n - 1 || !a || !b){puts("0"); return 0;}
  78. if (n == 1) A[1][0] = 1;
  79. else solve(0,n - 2);
  80. printf("%I64d\n",1ll * A[1][a + b - 2] * C(a + b - 2,a - 1) % P);
  81. return 0;
  82. }

CF960G Bandit Blues 【第一类斯特林数 + 分治NTT】的更多相关文章

  1. CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增

    传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...

  2. [CF960G]Bandit Blues(第一类斯特林数+分治卷积)

    Solution: ​ 先考虑前缀,设 \(f(i, j)\) 为长度为 \(i\) 的排列中满足前缀最大值为自己的数有 \(j\) 个的排列数. 假设新加一个数 \(i+1\) 那么会有: \[ f ...

  3. CF960G Bandit Blues 第一类斯特林数+分治+FFT

    题目传送门 https://codeforces.com/contest/960/problem/G 题解 首先整个排列的最大值一定是 \(A\) 个前缀最大值的最后一个,也是 \(B\) 个后缀最大 ...

  4. CF960G-Bandit Blues【第一类斯特林数,分治,NTT】

    正题 题目链接:https://www.luogu.com.cn/problem/CF960G 题目大意 求有多少个长度为\(n\)的排列,使得有\(A\)个前缀最大值和\(B\)个后缀最大值. \( ...

  5. Codeforces960G Bandit Blues 【斯特林数】【FFT】

    题目大意: 求满足比之前的任何数小的有A个,比之后的任何数小的有B个的长度为n的排列个数. 题目分析: 首先写出递推式,设s(n,k)表示长度为n的排列,比之前的数小的数有k个. 我们假设新加入的数为 ...

  6. CF960G Bandit Blues 分治+NTT(第一类斯特林数)

    $ \color{#0066ff}{ 题目描述 }$ 给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大 ...

  7. 【CF960G】Bandit Blues(第一类斯特林数,FFT)

    [CF960G]Bandit Blues(第一类斯特林数,FFT) 题面 洛谷 CF 求前缀最大值有\(a\)个,后缀最大值有\(b\)个的长度为\(n\)的排列个数. 题解 完完全全就是[FJOI] ...

  8. CF960G Bandit Blues(第一类斯特林数)

    传送门 可以去看看litble巨巨关于第一类斯特林数的总结 设\(f(i,j)\)为\(i\)个数的排列中有\(j\)个数是前缀最大数的方案数,枚举最小的数的位置,则有递推式\(f(i,j)=f(i- ...

  9. 【cf960G】G. Bandit Blues(第一类斯特林数)

    传送门 题意: 现在有一个人分别从\(1,n\)两点出发,包中有一个物品价值一开始为\(0\),每遇到一个价值比包中物品高的就交换两个物品. 现在已知这个人从左边出发交换了\(a\)次,从右边出发交换 ...

随机推荐

  1. [算法总结] 20 道题搞定 BAT 面试——二叉树

    本文首发于我的个人博客:尾尾部落 0. 几个概念 完全二叉树:若二叉树的高度是h,除第h层之外,其他(1~h-1)层的节点数都达到了最大个数,并且第h层的节点都连续的集中在最左边.想到点什么没?实际上 ...

  2. appium+python+unittest 测试用例的几种加载执行方式

    利用python进行测试时,测试用例的加载方式有2种: 一种是通过unittest.main()来启动所需测试的测试模块:  一种是添加到testsuite集合中再加载所有的被测试对象,而testsu ...

  3. ipython快捷键操作及常用命令

    Ipython shell命令- Ctrl-P 或上箭头键 后向搜索命令历史中以当前输入的文本开头的命令- Ctrl-N 或下箭头键 前向搜索命令历史中以当前输入的文本开头的命令- Ctrl-R 按行 ...

  4. NO.4:自学python之路------内置方法、装饰器、迭代器

    引言 是时候开始新的Python学习了,最近要考英语,可能不会周更,但是尽量吧. 正文 内置方法 Python提供给了使用者很多内置方法,可以便于编程使用.这里就来挑选其中大部分的内置方法进行解释其用 ...

  5. mysql 伪列

    select  @rownum:=@rownum+1 AS rownum,b.* from (SELECT @rownum:=0) r ,goods_description_new  b

  6. LIFI热火下的VLC基本链路、标准及发展问题

    和白炽及荧光灯相比,白光发光二极管(LED)具有寿命长.光效高.功耗低.无辐射.安全性好.可靠性高等特点,被称为"绿色照明"并得到迅猛发展.白光LED在未来市场极具竞争力.世界范围 ...

  7. IDEA下载插件超时的原因

    setting中红框的对勾去掉就可以下载插件了

  8. 2017-2018-2 1723 『Java程序设计』课程 结对编程练习-四则运算-最后阶段

    2017-2018-2 1723 『Java程序设计』课程 结对编程练习-四则运算-最后阶段 最后的一周,时间越来越紧张,因为之前的拖沓和一些事情的耽误,导致了如今的紧张,这一周应该是我们小组效率最高 ...

  9. Java 面试 --- 3

    上一篇,我们给出了大概35个题目,都是基础知识,有童鞋反映题目过时了,其实不然,这些是基础中的基础,但是也是必不可少的,面试题目中还是有一些基础题目的,我们本着先易后难的原则,逐渐给出不同级别的题目, ...

  10. 软工1816 · Beta冲刺(1/7)

    团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 完成beta冲刺阶段的任务安排 整理博客 接下来的计划 & 还剩下哪些 ...