CF960G Bandit Blues(第一类斯特林数)
可以去看看litble巨巨关于第一类斯特林数的总结
设\(f(i,j)\)为\(i\)个数的排列中有\(j\)个数是前缀最大数的方案数,枚举最小的数的位置,则有递推式\(f(i,j)=f(i-1,j-1)+(i-1)\times f(i-1,j)\)
这个就是第一类斯特林数
第一类斯特林数中\(S_1(n,m)\)是\(\prod_{i=0}^{n-1}(x+i)\)中\(x^m\)的系数,可以用分治\(FFT\)做到\(O(n\log^2n)\)的复杂度
首先\(n\)肯定是前缀最大值,所以题目要求的\(a-1\)个数一定都在\(n\)前面,\(b-1\)个数一定都在\(n\)后面。设整个序列中没有\(n\),前缀最大值的位置分别为\(p_1,p_2,...,p_k\),可以把每个\([p_i,p_{i+1}-1]\)看成一块,那么可以产生\(a+b-2\)块,然后选择其中的\(b-1\)块整个翻转然后放到\(n\)的后面,所以答案就是$$S_1(n-1,a+b-2)\times C_{a+b-2}^{b-1}$$
//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
char buf[1<<21],*p1=buf,*p2=buf;
inline char getc(){return p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++;}
int read(){
R int res,f=1;R char ch;
while((ch=getc())>'9'||ch<'0')(ch=='-')&&(f=-1);
for(res=ch-'0';(ch=getc())>='0'&&ch<='9';res=res*10+ch-'0');
return res*f;
}
const int N=5e5+5,P=998244353,Gi=332748118;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int ksm(R int x,R int y){
R int res=1;
for(;y;y>>=1,x=mul(x,x))if(y&1)res=mul(res,x);
return res;
}
int A[19][N],O[N],r[N];
int n,m,a,b;
void NTT(int *A,int ty,int lim){
fp(i,0,lim-1)if(i<r[i])swap(A[i],A[r[i]]);
for(R int mid=1;mid<lim;mid<<=1){
R int I=(mid<<1),Wn=ksm(ty==1?3:Gi,(P-1)/I);O[0]=1;
fp(i,1,mid-1)O[i]=mul(O[i-1],Wn);
for(R int j=0;j<lim;j+=I)for(R int k=0;k<mid;++k){
int x=A[j+k],y=mul(O[k],A[j+k+mid]);
A[j+k]=add(x,y),A[j+k+mid]=dec(x,y);
}
}if(ty==-1)for(R int i=0,inv=ksm(lim,P-2);i<lim;++i)A[i]=mul(A[i],inv);
}
void solve(int ql,int qr,int d){
if(ql==qr)return (void)(A[d][0]=ql,A[d][1]=1);
int mid=(ql+qr)>>1,lim=1,l=0;
while(lim<=qr-ql+1)lim<<=1,++l;
solve(ql,mid,d),solve(mid+1,qr,d+1);
fp(i,0,lim-1)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));
fp(i,mid-ql+2,lim-1)A[d][i]=0;
fp(i,qr-mid+1,lim-1)A[d+1][i]=0;
NTT(A[d],1,lim),NTT(A[d+1],1,lim);
fp(i,0,lim-1)A[d][i]=mul(A[d][i],A[d+1][i]);
NTT(A[d],-1,lim);
}
int C(int n,int m){
int k1=1,k2=1;
fp(i,n-m+1,n)k1=mul(k1,i);
fp(i,1,m)k2=mul(k2,i);
return mul(k1,ksm(k2,P-2));
}
int main(){
// freopen("testdata.in","r",stdin);
n=read(),a=read(),b=read();
if(!a||!b||a+b-2>n-1)return puts("0"),0;
if(n==1)return puts("1"),0;
solve(0,n-2,0);
printf("%d\n",mul(A[0][a+b-2],C(a+b-2,b-1)));
return 0;
}
CF960G Bandit Blues(第一类斯特林数)的更多相关文章
- 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\) 个后缀最大 ...
- 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 【第一类斯特林数 + 分治NTT】
题目链接 CF960G 题解 同FJOI2016只不过数据范围变大了 考虑如何预处理第一类斯特林数 性质 \[x^{\overline{n}} = \sum\limits_{i = 0}^{n}\be ...
- CF960G Bandit Blues 分治+NTT(第一类斯特林数)
$ \color{#0066ff}{ 题目描述 }$ 给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大 ...
- 【cf960G】G. Bandit Blues(第一类斯特林数)
传送门 题意: 现在有一个人分别从\(1,n\)两点出发,包中有一个物品价值一开始为\(0\),每遇到一个价值比包中物品高的就交换两个物品. 现在已知这个人从左边出发交换了\(a\)次,从右边出发交换 ...
- CF960G(第一类斯特林数)
题目 CF960G 做法 设\(f(i,j)\)为\(i\)个数的序列,有\(j\)个前缀最大值的方案数 我们考虑每次添一个最小数,则有:\(f(i,j)=f(i-1,j)+(i-1)*f(i-1,j ...
随机推荐
- EasyDarwin开源流媒体云平台中boost Base64编解码后与源长度不匹配的bug
本文转自EasyDarwin团队Alex的博客:http://blog.csdn.net/cai6811376 EasyDarwin云平台中部分协议使用了Base64编码昨晚报文通信的载体.比如在对摄 ...
- EasyDarwin接入ffmpeg实现264转图片快照功能
本文转自:http://blog.csdn.net/cai6811376/article/details/51774467 EasyDarwin一直坚持开源精神,所以我们着手把EasyDarwin中使 ...
- EasyDarwin流媒体云平台架构
EasyDarwin目前正在做的开源流媒体云平台架构:
- 预料外的变量值的改变是很多bug的源头
- ElasticSearch(七)容错机制
一.关于横向扩容 PUT /test_index { "settings" : { "number_of_shards" : 3, "number_o ...
- python自动化运维九:Playbook
playbook:playbook 由一个或多个 ‘plays’ 组成.它的内容是一个以 ‘plays’ 为元素的列表.在 play 之中,一组机器被映射为定义好的角色.在 ansible 中,pla ...
- duilib查看过的资料整理
1.duilib中各个类的简单介绍 2.源码分析 3.各个控件可以设置的属性 4.duilib的消息流程处理 5.工程编译入门 6.MFC中混合使用duilib制作界面 7.从Win32窗口到duil ...
- Dockder的CS模式:
Docker的守护进程一直运行, yw1989@ubuntu:~$ ps -ef | grep docker : 就是docxker的守护进程 root : ? :: /usr/bin/dockerd ...
- ThinkPHP验证码不现实的处理方法
ThinkPHP测试的时候遇到验证码不显示的问题,主要解决思路如下: 1.php.ini是否开启gd库: 2.页面编码是否一致: 3.检查页面头部信息BOM,这是最主要的,把下面代码复制到根目录下,然 ...
- Android Weekly Notes Issue #252
Android Weekly Issue #252 April 9th, 2017 Android Weekly Issue #252. 本期内容: 变化的渐变背景实现; Kotlin 1.1特性; ...