CF960G Bandit Blues 分治+NTT(第一类斯特林数)
$ \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(第一类斯特林数)相关推荐
- CF960G-Bandit Blues【第一类斯特林数,分治,NTT】
正题 题目链接:https://www.luogu.com.cn/problem/CF960G 题目大意 求有多少个长度为nnn的排列,使得有AAA个前缀最大值和BBB个后缀最大值. 0≤n,A,B≤ ...
- 【2019雅礼集训】【CF 960G】【第一类斯特林数】【NTT多项式】permutation
目录 题意 输入格式 输出格式 思路 代码 题意 找有多少个长度为n的排列,使得从左往右数,有a个元素比之前的所有数字都大,从右往左数,有b个元素比之后的所有数字都大. n<=2*10^5,a, ...
- 第一类斯特林数 / 第二类斯特林数 / 贝尔数 小结
第一类斯特林数 有 nnn 个不同的小球,将它们串成 mmm 条项链,有多少种不同的方案? 第一类斯特林数的表示方法为 [nm]\left[\begin{matrix}n\\m\end{matrix} ...
- 第一类斯特林数学习记录
最近做题有时会碰到斯特林数(Stirling数),就觉得好好的学习一番,于是呢,写下这篇博客,来记录一些知识 简单介绍 第一类斯特林数表示表示将 n 个不同元素构成m个圆排列的数目.--百度百科 第一 ...
- 洛谷P4609 [FJOI2016]建筑师 【第一类斯特林数】
题目链接 洛谷P4609 题解 感性理解一下: 一神带\(n\)坑 所以我们只需将除了\(n\)外的\(n - 1\)个元素分成\(A + B - 2\)个集合,每个集合选出最大的在一端,剩余进行排列 ...
- 建筑师 第一类斯特林数
文章目录 目录 题意: 思路: 目录 题意: 给你一个nnn的排列,排列中的数代表他的高度,问你有多少个排列能使得从左边能看到aaa个建筑,从右边能看到bbb个建筑. 如果建筑iii左边没有任何比他高 ...
- [HDU 3625] Examining the Rooms(第一类斯特林数)
Examining the Rooms problem solution code problem hdu 3625 solution 之前考试有一道题:最多砸开 kkk 扇门,采取最有操作,求把 n ...
- [数学最安逸][UVa1638改编][第一类斯特林数+组合数]杆子的排列
有高为1,2,3,...,n的杆子各一根排成一行.从左边能看到l根,从右边能看到r根,求有多少种可能. (l,r <= 200,n <= 200000) 给出T 组数据 (T <= ...
- 【BJOI2019】勘破神机(下降幂转自然幂)(第一类斯特林数)(特征方程)
传送门 题解: 完全自己推出来的第一道数学神题. 首先我们知道宽度为222的部分方案数是斐波那契数列. 设fnf_nfn表示长度为nnn的时候方案数,题目要求的实际上是这个东西: ∑n=lr(fnk ...
- zoj3344 第一类斯特林数+java大数
题意:有个游戏,两个人玩.有n个卡片,洗牌后放入编号为1到n的盒子里,然后两个人轮流做如下操作,拿出盒子中编号最小的卡片k,然后再去编号为k的盒子中拿出卡片,依次类推,直到没有卡片可拿为止.拿走最后一 ...
最新文章
- Console-算法-一个偶数总能表示为两个素数之和
- 《Visual C++数字图像模式识别技术详解(第2版)》一3.4 形状特征
- Activemq-In-action(二)
- 在Ubuntu服务器上打开第二个控制台会话
- STM32那点事(1)_STM32F40_41xx启动文件详解
- Array(数组-转树)
- 60-100-020-使用-MySQL 的Show Profile命令
- opencv imshow 窗口无响应 the window does not seem to be responding. do you want to force
- Spark序列化入门
- 献礼厦门大学百年校庆!亿联网络「沉浸式交互教室」首次亮相即惊艳
- cpu散片是什么意思?
- 《数据库原理与应用》习题
- C#读取srt字幕格式文件显示字幕
- java下载m3u8转ts合成mp4
- DSP TMS320C5509A之DAC8164
- MySql之Sql注入的产生与预防
- Hadoop集群中添加Snappy解压缩库
- 统计英文句子中有多少个英文单词 单词之间用空格分开
- cae计算机仿真分析技术,仿真分析工作在研发中的定位
- FastDFS分布式文件系统集群安装与配置
热门文章
- Vue中computed,methods,watch用法上的异同
- 【译】EntityFramework6与EntityFrameworkCore的区别
- Ubuntu 14.04/16.04 与 Windows 10 周年版 Ubuntu Bash 性能对比
- 2015年Java开发岗位面试题归类
- 【js与jquery】导航下拉菜单效果
- 正在发生的景象--从大众消费到圈层经济
- 一种基于annotation的Spring-mvc权限控制方法
- 工作效率上的错觉(转载)
- mysql 查询结果插入另一张表_详解Mysql的锁机制
- Android中AndFix使用