【CF960G】Bandit Blues

题面

洛谷

题解

思路和这道题一模一样,这里仅仅阐述优化的方法。

看看答案是什么:

\[Ans=C(a+b-2,a-1)\centerdot s(n-1,a+b-2)
\]

组合数我们已经可以\(O(N)\)求了,主要是第一类斯特林数存在问题。

考虑它的转移:

\[s(n,m)=s(n-1,m-1)+(n-1)*s(n-1,m)
\]

根据这个转移,我们写出它\(n\)固定时的生成函数

\[G(x)=\prod_{i=0}^{n-1}(x+i)
\]

然后每一个\(s(n,m)\)就是升序第\(m\)项的次数。

为什么生成函数是这个?

引用\(yyb\)的:

把\(n\)为定值时的所有的第一类斯特林数按照\(n\)分类分成行,发现每次的\(s(n,m)\)转移必定要从\(n−1\)行转移过来,而每次转移都是\(m−1\)变到\(m\),系数为\(1\),因此有一项\(x\),同理有一项\(n−1\),因此就可以得到上面的那个生成函数。

然后对于这个东西我们用分治+\(NTT\)就可以\(O(n\log^2)\)地做了。

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
const int Mod = 998244353;
int fpow(int x, int y) {
int res = 1;
while (y) {
if (y & 1) res = 1ll * res * x % Mod;
y >>= 1;
x = 1ll * x * x % Mod;
}
return res;
}
const int G = 3, iG = fpow(G, Mod - 2);
const int MAX_N = 3e5 + 5;
int rev[MAX_N], Limit;
void NTT(vector<int> &p, int op) {
for (int i = 0; i < Limit; i++) if (i < rev[i]) swap(p[i], p[rev[i]]);
for (int i = 1; i < Limit; i <<= 1) {
int rot = fpow(op == 1 ? G : iG, (Mod - 1) / (i << 1));
for (int j = 0; j < Limit; j += (i << 1)) {
int w = 1;
for (int k = 0; k < i; k++, w = 1ll * w * rot % Mod) {
int x = p[j + k], y = 1ll * w * p[i + j + k] % Mod;
p[j + k] = (x + y) % Mod, p[i + j + k] = (x - y + Mod) % Mod;
}
}
}
if (op == -1) {
int inv = fpow(Limit, Mod - 2);
for (int i = 0; i < Limit; i++) p[i] = 1ll * inv * p[i] % Mod;
}
} vector<int> mul(vector<int> &A, vector<int> &B) {
static vector<int> C;
C.clear();
int p = 0, sz = A.size() + B.size() - 2;
for (Limit = 1; Limit <= sz + 1; Limit <<= 1, ++p);
for (int i = 0; i < Limit; i++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (p - 1));
A.resize(Limit), B.resize(Limit);
NTT(A, 1), NTT(B, 1);
for (int i = 0; i < Limit; i++) C.push_back(1ll * A[i] * B[i] % Mod);
NTT(C, -1);
return C;
}
vector<int> Div(int l, int r) {
vector<int> L, R;
if (l == r) return {l, 1};
int mid = (l + r) >> 1;
L = Div(l, mid), R = Div(mid + 1, r);
return mul(L, R);
}
int fac(int x) { int res = 1; for (int i = 1; i <= x; i++) res = 1ll * res * i % Mod; return res; }
int C(int n, int m) {
if (m > n) return 0;
else return 1ll * fac(n) * fpow(fac(m), Mod - 2) % Mod * fpow(fac(n - m), Mod - 2) % Mod;
}
vector<int> Ans;
int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
#endif
int N, A, B;
cin >> N >> A >> B;
if (!A || !B || A + B - 2 > N - 1) return puts("0") & 0;
if (N == 1) return puts("1") & 0;
Ans = Div(0, N - 2);
printf("%d\n", (int)(1ll * Ans[A + B - 2] * C(A + B - 2, A - 1) % Mod));
return 0;
}

【CF960G】Bandit Blues的更多相关文章

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

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

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

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

  3. Luogu P4609 [FJOI2016]建筑师&&CF 960G Bandit Blues

    考虑转化题意,我们发现其实就是找一个长度为\(n\)的全排列,使得这个排列有\(A\)个前缀最大值,\(B\)个后缀最大值,求方案数 我们考虑把最大值拎出来单独考虑,同时定义一些数的顺序排列为单调块( ...

  4. Python高手之路【六】python基础之字符串格式化

    Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两者并存.[PEP-3101] This ...

  5. 【原】谈谈对Objective-C中代理模式的误解

    [原]谈谈对Objective-C中代理模式的误解 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这篇文章主要是对代理模式和委托模式进行了对比,个人认为Objective ...

  6. 【原】FMDB源码阅读(三)

    [原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...

  7. 【原】Android热更新开源项目Tinker源码解析系列之一:Dex热更新

    [原]Android热更新开源项目Tinker源码解析系列之一:Dex热更新 Tinker是微信的第一个开源项目,主要用于安卓应用bug的热修复和功能的迭代. Tinker github地址:http ...

  8. 【调侃】IOC前世今生

    前些天,参与了公司内部小组的一次技术交流,主要是针对<IOC与AOP>,本着学而时习之的态度及积极分享的精神,我就结合一个小故事来初浅地剖析一下我眼中的“IOC前世今生”,以方便初学者能更 ...

  9. Python高手之路【三】python基础之函数

    基本数据类型补充: set 是一个无序且不重复的元素集合 class set(object): """ set() -> new empty set object ...

随机推荐

  1. 协议森林08 不放弃 (TCP协议与流通信)

    作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation Control Protocol)协议与IP ...

  2. Yii2.0 发送邮件时中文附件乱码的问题

    yii自带的邮件类使用的是MIME 协议,发送附件时用的是MIME 协议的 Content-disposition扩展,用扩展下载中文名称的附件时有时会正常,有时会乱码. 只需找到如下文件 的如下方法 ...

  3. Kali-linux在树莓派上破解无线网络

    大部分的命令可以正常的运行在BackTrack5或Kali上.在Kali上可以实现的无线渗透测试,在树莓派上也可以运行.在第1章中介绍了在树莓派上安装Kali Linux操作系统,下面将介绍在树莓派上 ...

  4. leetcode231 2的幂 leetcode342 4的幂 leetcode326 3的幂

    1.2的幂 正确写法: class Solution { public: bool isPowerOfTwo(int n) { ) return false; )) == ; } }; 错误写法1: ...

  5. Unity3D-飞机拖尾效果

    1.插件准备 unity3d官网,Assert Store搜索Cartoon_airplane 插件 2.拖尾效果实现 飞机显示 拖尾组件设计 在airplane_02下 右键 Effects-Tra ...

  6. Linux 启动进程结束进程通用代码

    linux启动springboot项目 start.sh #!/bin/sh rm -f tpid nohup java -jar restDate--SNAPSHOT.jar --spring.pr ...

  7. 【luogu P2827 蚯蚓】 题解

    题目链接:https://www.luogu.org/problemnew/show/P2827 35分:暴力sortO(mnlogn). 80分:考虑到每次不好维护不被切的点+q,正难则反.改成维护 ...

  8. nyoi 42(欧拉回路)

    http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=42 一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ...

  9. EF Core 2.1 支持数据库一对一关系

    在使用EF Core和设计数据库的时候,通常一对多.多对多关系使用得比较多,但是一对一关系使用得就比较少了.最近我发现实际上EF Core很好地支持了数据库的一对一关系. 数据库 我们先来看看SQL ...

  10. 03_Docker入门(上)之容器创建、容器使用、容器删除

    运维架构服务docker:docker入门 一.确保docker就绪 查看docker程序是否存在,功能是否正常 Docker可执行程序的info命令,该命令会返回所有容器和镜像的数量.Docker使 ...