$ \color{#0066ff}{ 题目描述 }$

给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大值的数的个数,求长度为 \(n\) 的排列中满足 \(A = a\) 且 \(B = b\) 的排列个数。\(n \le 10^5\),答案对 \(998244353\) 取模。

\(\color{#0066ff}{输入格式}\)

三个整数n,a,b

\(\color{#0066ff}{输出格式}\)

方案数

\(\color{#0066ff}{输入样例}\)

1 1 12 1 12 2 15 2 2

\(\color{#0066ff}{输出样例}\)

10122

\(\color{#0066ff}{数据范围与提示}\)

\(N\) ( $1<=N<=10^{5} $ ), $A $and $ B$ ( $0<=A,B<=N $).

\(\color{#0066ff}{题解}\)

显然当\(a+b-1>n\)时,无解

考虑DP, \(f[i][j]\)表示i的排列有j个前缀最大值的方案数

考虑枚举1的位置\(f[i][j] = f[i-1][j-1]+(i-1)*f[i-1][j]\)

这是第一类斯特林数

实际上第一维滚动之后,可以发现, 就是把整个数组移动一位再加上自己的值*dp轮数

就相当于第i轮有i次操作,有1的方案取一个球,有i-1的方案一个球不取

于是构造生成函数\(\begin{aligned}\prod_{i=0}^{n-2}(x+i)\end{aligned}\)

本来应该是n-1的,实际上n的方案从1只转移n-1次, 所以-1

这个式子可以分治+NTT快速求出

最后还要组合一下,可以考虑每个产生贡献的值,a个和b个分别分成a-1和b-1段

最后再乘一个\(C_{a+b-2}^{a-1}\)即可

#include<bits/stdc++.h>
#define LL long long
LL in() {char ch; LL x = 0, f = 1;while(!isdigit(ch = getchar()))(ch == '-') && (f = -f);for(x = ch ^ 48; isdigit(ch = getchar()); x = (x << 1) + (x << 3) + (ch ^ 48));return x * f;
}
const int maxn = 4e5 + 10;
const int mod = 998244353;
int len, r[maxn];
using std::vector;
LL ksm(LL x, LL y) {LL re = 1LL;while(y) {if(y & 1) re = re * x % mod;x = x * x % mod;y >>= 1;}return re;
}
void FNTT(vector<int> &A, int flag) {A.resize(len);for(int i = 0; i < len; i++) if(i < r[i]) std::swap(A[i], A[r[i]]);for(int l = 1; l < len; l <<= 1) {int w0 = ksm(3, (mod - 1) / (l << 1));for(int i = 0; i < len; i += (l << 1)) {int w = 1, a0 = i, a1 = i + l;for(int k = 0; k < l; k++, a0++, a1++, w = 1LL * w0 * w % mod) {int tmp = 1LL * A[a1] * w % mod;A[a1] = ((A[a0] - tmp) % mod + mod) % mod;A[a0] = (A[a0] + tmp) % mod;}}}if(!(~flag)) {std::reverse(A.begin() + 1, A.end());int inv = ksm(len, mod - 2);for(int i = 0; i < len; i++) A[i] = 1LL * A[i] * inv % mod;}
}
vector<int> operator * (vector<int> A, vector<int> B) {int tot = A.size() + B.size() - 1;for(len = 1; len <= tot; len <<= 1);for(int i = 0; i < len; i++) r[i] = (r[i >> 1] >> 1) | ((i & 1) * (len >> 1));FNTT(A, 1), FNTT(B, 1);std::vector<int> ans;for(int i = 0; i < len; i++) ans.push_back(1LL * A[i] * B[i] % mod);FNTT(ans, -1);ans.resize(tot);return ans;
}
int n, a, b;
std::vector<int> work(int l, int r) {vector<int> ans;if(l == r) {ans.resize(2, 0);ans[1] += 1, ans[0] += l;return ans;}int mid = (l + r) >> 1;return work(l, mid) * work(mid + 1, r);
}
LL C(int x, int y) {LL ans1 = 1, ans2 = 1;for(int i = y + 1; i <= x; i++) ans1 = 1LL * ans1 * i % mod;for(int i = 1; i <= x - y; i++) ans2 = 1LL * ans2 * i % mod;return 1LL * ans1 * ksm(ans2, mod - 2) % mod;
}
int main() {n = in(), a = in(), b = in();if(!a || !b || a + b - 1 > n) return puts("0"), 0;if(n == 1) return puts("1"), 0;std::vector<int> ans;ans = work(0, n - 2);printf("%lld\n", 1LL * ans[a + b - 2] * C(a + b - 2, a - 1) % mod);return 0;
}

转载于:https://www.cnblogs.com/olinr/p/10580873.html

CF960G Bandit Blues 分治+NTT(第一类斯特林数)相关推荐

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

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

  2. 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT多项式】permutation

    目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...

  3. 第一类斯特林数 / 第二类斯特林数 / 贝尔数 小结

    第一类斯特林数 有 nnn 个不同的小球,将它们串成 mmm 条项链,有多少种不同的方案? 第一类斯特林数的表示方法为 [nm]\left[\begin{matrix}n\\m\end{matrix} ...

  4. 第一类斯特林数学习记录

    最近做题有时会碰到斯特林数(Stirling数),就觉得好好的学习一番,于是呢,写下这篇博客,来记录一些知识 简单介绍 第一类斯特林数表示表示将 n 个不同元素构成m个圆排列的数目.--百度百科 第一 ...

  5. 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】

    题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...

  6. 建筑师 第一类斯特林数

    文章目录 目录 题意: 思路: 目录 题意: 给你一个nnn的排列,排列中的数代表他的高度,问你有多少个排列能使得从左边能看到aaa个建筑,从右边能看到bbb个建筑. 如果建筑iii左边没有任何比他高 ...

  7. [HDU 3625] Examining the Rooms(第一类斯特林数)

    Examining the Rooms problem solution code problem hdu 3625 solution 之前考试有一道题:最多砸开 kkk 扇门,采取最有操作,求把 n ...

  8. [数学最安逸][UVa1638改编][第一类斯特林数+组合数]杆子的排列

    有高为1,2,3,...,n的杆子各一根排成一行.从左边能看到l根,从右边能看到r根,求有多少种可能. (l,r <= 200,n <= 200000) 给出T 组数据 (T <= ...

  9. 【BJOI2019】勘破神机(下降幂转自然幂)(第一类斯特林数)(特征方程)

    传送门 题解: 完全自己推出来的第一道数学神题. 首先我们知道宽度为222的部分方案数是斐波那契数列. 设fnf_nfn​表示长度为nnn的时候方案数,题目要求的实际上是这个东西: ∑n=lr(fnk ...

  10. zoj3344 第一类斯特林数+java大数

    题意:有个游戏,两个人玩.有n个卡片,洗牌后放入编号为1到n的盒子里,然后两个人轮流做如下操作,拿出盒子中编号最小的卡片k,然后再去编号为k的盒子中拿出卡片,依次类推,直到没有卡片可拿为止.拿走最后一 ...

最新文章

  1. Console-算法-一个偶数总能表示为两个素数之和
  2. 《Visual C++数字图像模式识别技术详解(第2版)》一3.4 形状特征
  3. Activemq-In-action(二)
  4. 在Ubuntu服务器上打开第二个控制台会话
  5. STM32那点事(1)_STM32F40_41xx启动文件详解
  6. Array(数组-转树)
  7. 60-100-020-使用-MySQL 的Show Profile命令
  8. opencv imshow 窗口无响应 the window does not seem to be responding. do you want to force
  9. Spark序列化入门
  10. 献礼厦门大学百年校庆!亿联网络「沉浸式交互教室」首次亮相即惊艳
  11. cpu散片是什么意思?
  12. 《数据库原理与应用》习题
  13. C#读取srt字幕格式文件显示字幕
  14. java下载m3u8转ts合成mp4
  15. DSP TMS320C5509A之DAC8164
  16. MySql之Sql注入的产生与预防
  17. Hadoop集群中添加Snappy解压缩库
  18. 统计英文句子中有多少个英文单词 单词之间用空格分开
  19. cae计算机仿真分析技术,仿真分析工作在研发中的定位
  20. FastDFS分布式文件系统集群安装与配置

热门文章

  1. Vue中computed,methods,watch用法上的异同
  2. 【译】EntityFramework6与EntityFrameworkCore的区别
  3. Ubuntu 14.04/16.04 与 Windows 10 周年版 Ubuntu Bash 性能对比
  4. 2015年Java开发岗位面试题归类
  5. 【js与jquery】导航下拉菜单效果
  6. 正在发生的景象--从大众消费到圈层经济
  7. 一种基于annotation的Spring-mvc权限控制方法
  8. 工作效率上的错觉(转载)
  9. mysql 查询结果插入另一张表_详解Mysql的锁机制
  10. Android中AndFix使用