CF960G Bandit Blues 【第一类斯特林数 + 分治NTT】
题目链接
题解
同FJOI2016只不过数据范围变大了
考虑如何预处理第一类斯特林数
性质
\]
分治\(NTT\)即可在\(O(nlog^2n)\)的时间内预处理出同一个\(n\)的所有\(\begin{bmatrix} n \\ i \end{bmatrix}\)
其实还有比较优美的倍增\(fft\)的\(O(nlogn)\)的方法
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<vector>
#include<queue>
#include<cmath>
#include<map>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define cls(s,v) memset(s,v,sizeof(s))
#define mp(a,b) make_pair<int,int>(a,b)
#define cp pair<int,int>
using namespace std;
const int maxn = 400005,maxm = 100005,INF = 0x3f3f3f3f;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = 0; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 1) + (out << 3) + c - 48; c = getchar();}
return flag ? out : -out;
}
const int P = 998244353,G = 3;
inline int qpow(int a,int b){
int re = 1;
for (; b; b >>= 1,a = 1ll * a * a % P)
if (b & 1) re = 1ll * re * a % P;
return re;
}
int R[maxn];
void NTT(int* a,int n,int f){
for (int i = 0; i < n; i++) if (i < R[i]) swap(a[i],a[R[i]]);
for (int i = 1; i < n; i <<= 1){
int gn = qpow(G,(P - 1) / (i << 1));
for (int j = 0; j < n; j += (i << 1)){
int g = 1,x,y;
for (int k = 0; k < i; k++,g = 1ll * g * gn % P){
x = a[j + k],y = 1ll * a[j + k + i] * g % P;
a[j + k] = (x + y) % P,a[j + k + i] = (P - y + x) % P;
}
}
}
if (f == 1) return;
int nv = qpow(n,P - 2); reverse(a + 1,a + n);
for (int i = 0; i < n; i++) a[i] = 1ll * a[i] * nv % P;
}
int n,a,b,A[20][maxn],deg[20],cnt;
void solve(int l,int r){
if (l == r){
cnt++; A[cnt][0] = l; A[cnt][1] = 1; deg[cnt] = 1;
return;
}
int mid = l + r >> 1;
solve(l,mid); solve(mid + 1,r);
int a = cnt - 1,b = cnt,n = 1,L = 0;
while (n <= deg[a] + deg[b]) n <<= 1,L++;
for (int i = 1; i < n; i++) R[i] = (R[i >> 1] >> 1) | ((i & 1) << (L - 1));
for (int i = deg[a] + 1; i < n; i++) A[a][i] = 0;
for (int i = deg[b] + 1; i < n; i++) A[b][i] = 0;
NTT(A[a],n,1); NTT(A[b],n,1);
for (int i = 0; i < n; i++) A[a][i] = 1ll * A[a][i] * A[b][i] % P;
NTT(A[a],n,-1);
cnt--;
deg[a] += deg[b];
}
int C(int n,int m){
if (n < m) return 0;
int re = 1;
for (int i = 1; i <= m; i++)
re = 1ll * re * (n - i + 1) % P * qpow(i,P - 2) % P;
return re;
}
int S[100][100];
int main(){
n = read(); a = read(); b = read();
if (a + b - 2 > n - 1 || !a || !b){puts("0"); return 0;}
if (n == 1) A[1][0] = 1;
else solve(0,n - 2);
printf("%I64d\n",1ll * A[1][a + b - 2] * C(a + b - 2,a - 1) % P);
return 0;
}
CF960G Bandit Blues 【第一类斯特林数 + 分治NTT】的更多相关文章
- CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增
传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...
- [CF960G]Bandit Blues(第一类斯特林数+分治卷积)
Solution: 先考虑前缀,设 \(f(i, j)\) 为长度为 \(i\) 的排列中满足前缀最大值为自己的数有 \(j\) 个的排列数. 假设新加一个数 \(i+1\) 那么会有: \[ f ...
- CF960G Bandit Blues 第一类斯特林数+分治+FFT
题目传送门 https://codeforces.com/contest/960/problem/G 题解 首先整个排列的最大值一定是 \(A\) 个前缀最大值的最后一个,也是 \(B\) 个后缀最大 ...
- CF960G-Bandit Blues【第一类斯特林数,分治,NTT】
正题 题目链接:https://www.luogu.com.cn/problem/CF960G 题目大意 求有多少个长度为\(n\)的排列,使得有\(A\)个前缀最大值和\(B\)个后缀最大值. \( ...
- Codeforces960G Bandit Blues 【斯特林数】【FFT】
题目大意: 求满足比之前的任何数小的有A个,比之后的任何数小的有B个的长度为n的排列个数. 题目分析: 首先写出递推式,设s(n,k)表示长度为n的排列,比之前的数小的数有k个. 我们假设新加入的数为 ...
- CF960G Bandit Blues 分治+NTT(第一类斯特林数)
$ \color{#0066ff}{ 题目描述 }$ 给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大 ...
- 【CF960G】Bandit Blues(第一类斯特林数,FFT)
[CF960G]Bandit Blues(第一类斯特林数,FFT) 题面 洛谷 CF 求前缀最大值有\(a\)个,后缀最大值有\(b\)个的长度为\(n\)的排列个数. 题解 完完全全就是[FJOI] ...
- CF960G Bandit Blues(第一类斯特林数)
传送门 可以去看看litble巨巨关于第一类斯特林数的总结 设\(f(i,j)\)为\(i\)个数的排列中有\(j\)个数是前缀最大数的方案数,枚举最小的数的位置,则有递推式\(f(i,j)=f(i- ...
- 【cf960G】G. Bandit Blues(第一类斯特林数)
传送门 题意: 现在有一个人分别从\(1,n\)两点出发,包中有一个物品价值一开始为\(0\),每遇到一个价值比包中物品高的就交换两个物品. 现在已知这个人从左边出发交换了\(a\)次,从右边出发交换 ...
随机推荐
- [算法总结] 20 道题搞定 BAT 面试——二叉树
本文首发于我的个人博客:尾尾部落 0. 几个概念 完全二叉树:若二叉树的高度是h,除第h层之外,其他(1~h-1)层的节点数都达到了最大个数,并且第h层的节点都连续的集中在最左边.想到点什么没?实际上 ...
- appium+python+unittest 测试用例的几种加载执行方式
利用python进行测试时,测试用例的加载方式有2种: 一种是通过unittest.main()来启动所需测试的测试模块: 一种是添加到testsuite集合中再加载所有的被测试对象,而testsu ...
- ipython快捷键操作及常用命令
Ipython shell命令- Ctrl-P 或上箭头键 后向搜索命令历史中以当前输入的文本开头的命令- Ctrl-N 或下箭头键 前向搜索命令历史中以当前输入的文本开头的命令- Ctrl-R 按行 ...
- NO.4:自学python之路------内置方法、装饰器、迭代器
引言 是时候开始新的Python学习了,最近要考英语,可能不会周更,但是尽量吧. 正文 内置方法 Python提供给了使用者很多内置方法,可以便于编程使用.这里就来挑选其中大部分的内置方法进行解释其用 ...
- mysql 伪列
select @rownum:=@rownum+1 AS rownum,b.* from (SELECT @rownum:=0) r ,goods_description_new b
- LIFI热火下的VLC基本链路、标准及发展问题
和白炽及荧光灯相比,白光发光二极管(LED)具有寿命长.光效高.功耗低.无辐射.安全性好.可靠性高等特点,被称为"绿色照明"并得到迅猛发展.白光LED在未来市场极具竞争力.世界范围 ...
- IDEA下载插件超时的原因
setting中红框的对勾去掉就可以下载插件了
- 2017-2018-2 1723 『Java程序设计』课程 结对编程练习-四则运算-最后阶段
2017-2018-2 1723 『Java程序设计』课程 结对编程练习-四则运算-最后阶段 最后的一周,时间越来越紧张,因为之前的拖沓和一些事情的耽误,导致了如今的紧张,这一周应该是我们小组效率最高 ...
- Java 面试 --- 3
上一篇,我们给出了大概35个题目,都是基础知识,有童鞋反映题目过时了,其实不然,这些是基础中的基础,但是也是必不可少的,面试题目中还是有一些基础题目的,我们本着先易后难的原则,逐渐给出不同级别的题目, ...
- 软工1816 · Beta冲刺(1/7)
团队信息 队名:爸爸饿了 组长博客:here 作业博客:here 组员情况 组员1(组长):王彬 过去两天完成了哪些任务 完成beta冲刺阶段的任务安排 整理博客 接下来的计划 & 还剩下哪些 ...