codeforces960G. Bandit Blues
题目链接:codeforces960G
某蒟蒻的关于第一类斯特林数的一点理解QAQ:https://www.cnblogs.com/zhou2003/p/10780832.html
注意到当前序列的最大值会对前缀最大值和后缀最大值均产生\(1\)的贡献
那么当我们去掉这个最大值后,剩下\(n-1\)个元素,需要产生\(a-1\)个前缀最大值和\(b-1\)个后缀最大值,并且它们的位置会以最大值为界限分布在两侧
我们将剩下的\(n-1\)个元素分成\((a-1)+(b-1)\)组,每一组钦定最大值在最开头,那么每一个这样的划分就对应了一个合法的序列,最后答案就是\(S(n-1,a+b-2)*\dbinom{a+b-2}{a-1}\),其中\(S(n,m)\)表示第一类斯特林数
这样你就可以完成后两题了
那么对于第一题呢?我们有这个式子:
\]
于是分治+FFT求之,据说有\(O(nlogn)\)的倍增做法?我懒啊
#include<iostream>
#include<string.h>
#include<string>
#include<stdio.h>
#include<algorithm>
#include<math.h>
#include<vector>
#include<queue>
#include<map>
#include<set>
using namespace std;
#define lowbit(x) (x)&(-x)
#define rep(i,a,b) for (int i=a;i<=b;i++)
#define per(i,a,b) for (int i=a;i>=b;i--)
#define maxd 998244353
typedef long long ll;
const int N=100000;
const double pi=acos(-1.0);
int n,a,b,rev[400400];
ll s[20][400400];
int read()
{
int x=0,f=1;char ch=getchar();
while ((ch<'0') || (ch>'9')) {if (ch=='-') f=-1;ch=getchar();}
while ((ch>='0') && (ch<='9')) {x=x*10+(ch-'0');ch=getchar();}
return x*f;
}
ll qpow(ll x,int y)
{
ll ans=1;
while (y)
{
if (y&1) ans=(ans*x)%maxd;
x=(x*x)%maxd;
y>>=1;
}
return ans;
}
ll inv(ll x) {return qpow(x,maxd-2);}
ll C(int n,int m)
{
if (n<m) return 0;
ll ans=1;
per(i,n,n-m+1) ans=ans*i%maxd;
rep(i,1,m) ans=ans*inv(i)%maxd;
return ans;
}
void ntt(int lim,ll *a,int typ)
{
rep(i,0,lim-1)
if (i<rev[i]) swap(a[i],a[rev[i]]);
int mid;
for (mid=1;mid<lim;mid<<=1)
{
ll wn=qpow(3,(maxd-1)/(mid<<1));
int len=(mid<<1),sta,j;
if (typ==-1) wn=inv(wn);
for (sta=0;sta<lim;sta+=len)
{
ll w=1;
for (j=0;j<mid;j++,w=(w*wn)%maxd)
{
ll x=a[sta+j],y=a[sta+j+mid]*w%maxd;
a[sta+j]=(x+y)%maxd;
a[sta+j+mid]=(x+maxd-y)%maxd;
}
}
}
if (typ==-1)
{
int invn=inv(lim);
rep(i,0,lim-1) a[i]=a[i]*invn%maxd;
}
}
void solve(int l,int r,int d)
{
if (l==r) {s[d][0]=l;s[d][1]=1;return;}
int mid=(l+r)>>1;
solve(l,mid,d+1);
rep(i,0,mid-l+1) s[d][i]=s[d+1][i];
solve(mid+1,r,d+1);
int lim=1,cnt=0;
while (lim<=(r-l+1)) {lim<<=1;cnt++;}
rep(i,mid-l+2,lim) s[d][i]=0;
rep(i,r-mid+1,lim) s[d+1][i]=0;
rep(i,0,lim-1)
rev[i]=(rev[i>>1]>>1)|((i&1)<<(cnt-1));
ntt(lim,s[d],1);ntt(lim,s[d+1],1);
rep(i,0,lim-1) s[d][i]=s[d][i]*s[d+1][i]%maxd;
ntt(lim,s[d],-1);
}
int main()
{
n=read();a=read();b=read();
if ((n-1<a+b-2) || (!a) || (!b)) {printf("0");return 0;}
if (n==1) {printf("1");return 0;}
solve(0,n-2,0);
printf("%lld",C(a+b-2,a-1)*s[0][a+b-2]%maxd);
return 0;
}
codeforces960G. Bandit Blues的更多相关文章
- Codeforces960G Bandit Blues 【斯特林数】【FFT】
题目大意: 求满足比之前的任何数小的有A个,比之后的任何数小的有B个的长度为n的排列个数. 题目分析: 首先写出递推式,设s(n,k)表示长度为n的排列,比之前的数小的数有k个. 我们假设新加入的数为 ...
- 【CF960G】Bandit Blues(第一类斯特林数,FFT)
[CF960G]Bandit Blues(第一类斯特林数,FFT) 题面 洛谷 CF 求前缀最大值有\(a\)个,后缀最大值有\(b\)个的长度为\(n\)的排列个数. 题解 完完全全就是[FJOI] ...
- 【CF960G】Bandit Blues
[CF960G]Bandit Blues 题面 洛谷 题解 思路和这道题一模一样,这里仅仅阐述优化的方法. 看看答案是什么: \[ Ans=C(a+b-2,a-1)\centerdot s(n-1,a ...
- Luogu P4609 [FJOI2016]建筑师&&CF 960G Bandit Blues
考虑转化题意,我们发现其实就是找一个长度为\(n\)的全排列,使得这个排列有\(A\)个前缀最大值,\(B\)个后缀最大值,求方案数 我们考虑把最大值拎出来单独考虑,同时定义一些数的顺序排列为单调块( ...
- [CF960G] Bandit Blues
题意 给你三个正整数 \(n,a,b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大值的数的个数,求长度为 \(n\) 的排列中满足 \(A = a ...
- CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增
传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...
- 解题:CF960G Bandit Blues & FJOI 2016 建筑师
题面1 题面2 两个题推导是一样的,具体实现不一样,所以写一起了,以FJOI 2016 建筑师 的题面为标准 前后在组合意义下一样,现在只考虑前面,可以发现看到的这a个建筑将这一段划分成了a-1个区间 ...
- Codeforces 960G. Bandit Blues
Description 你需要构造一个长度为 \(n\) 的排列 , 使得一个数作为前缀最大值的次数为 \(A\) , 作为后缀最大值的次数为 \(B\) , 求满足要求的排列个数 . 题面 Solu ...
- CF960G Bandit Blues 【第一类斯特林数 + 分治NTT】
题目链接 CF960G 题解 同FJOI2016只不过数据范围变大了 考虑如何预处理第一类斯特林数 性质 \[x^{\overline{n}} = \sum\limits_{i = 0}^{n}\be ...
随机推荐
- sql 脚本编写之路 常用语句(一) 1.用一个表中的某一列更新另外一个表的某些列:
for ACCESS 数据库: update a, b set a.name=b.name1 where a.id=b.id for SQL Server 数据库: update a set a.na ...
- Flask实战第6天:视图函数Response返回值
视图函数的返回值会被自动转换为一个响应对象,Flask的转换逻辑如下: 如果返回的是一个合法的响应对象,则直接返回 可以使用make_response函数来创建Response对象,这个方法可以设置额 ...
- 网页三剑客:HTML+CSS+JavaScript 之JavaScript
JavaScript 简介 JavaScript 是互联网上最流行的脚本语言,这门语言可用于 HTML 和 web,更可广泛用于服务器.PC.笔记本电脑.平板电脑和智能手机等设备. JavaScrip ...
- async await详解
async await本身就是promise + generator的语法糖. 本文主要讲述以下内容 async awiat 实质 async await 主要特性 async await 实质 下面 ...
- SAP MM 明明有需求,为啥MRP RUN后没有PR单据产生?
SAP MM 明明有需求,为啥MRP RUN后没有PR单据产生? 用户报了一个问题说,对于物料号42011222的采购单 4500000156建好了,为啥PR没有自动生成 . 我们检查了物料的MRP ...
- appium+python搭建自动化测试框架_Appium元素定位(二)
Appium元素定位: 工具:Android\android-sdk\tools uiautomatorviewer.bat 1. id定位: self.driver.find_element_ ...
- [20190416]查看shared latch gets的变化.txt
[20190416]查看shared latch gets的变化.txt 1.环境:SYS@book> @ ver1PORT_STRING VERSION ...
- 基于FPM制作nginx RPM包
目录 环境 配置 FPM安装 环境 系统 其它 CentOS 7.5 需提前配置好epel 配置 [root@localhost ~]# yum clean all && yum ma ...
- c/c++ 右值引用,forward关键字
c++ forward关键字 forward的由来:模板函数中的推导类型,作为另一函数的参数时,不管实参是什么类型,作为另一个参数的实参时,都变成了左值.因为C++里规定函数的形参就是左值,不过调用侧 ...
- Linux(Manjaro) - IntelliJ IDEA (JetBrains) 字体模糊解决方法
Linux(Manjaro) - IntelliJ IDEA 字体模糊解决方法 解决方法非常简单, 只要安装 JetBrains 提供的 jre 即可 使用 Octopi 或者 pacman 安装名为 ...