CF960G
首先我们考虑$n$的情况,显然以$n$为分界线可以将整个序列分成两部分,就像这样:
、
那么我们考虑:在这个东西前面才会有前缀最大的统计,在这个东西后面才会有后缀最大的统计
这样就剩下了$n-1$个元素,而我们需要把这$n-1$个元素分成$A+B-2$个集合,然后把每个集合的最大的一个放在一端,然后剩余部分全排列
设一个集合中有$k$个元素,那么剩余元素全排列的方案数就是$(k-1)!$
考虑这也是对$k$个元素放在一个圆排列上的方案数,因此我们能搞出一个第一类斯特林数的表达式:
$S_{1}(n-1,A+B-2)$
然后考虑这几个集合在左右的分布,有:$C_{A+B-2}^{A-1}$
因此最终答案即为$S_{1}(n-1,A+B-2)C_{A+B-2}^{A-1}$
然后第一类斯特林数可以倍增$O(nlog_{2}n)$求解,因此能通过这题:
// luogu-judger-enable-o2
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define ll unsigned long long
#define uint unsigned int
using namespace std;
const uint mode=998244353;
uint pow_mul(uint x,uint y)
{
uint ret=1;
while(y)
{
if(y&1)ret=1ll*ret*x%mode;
x=1ll*x*x%mode,y>>=1;
}
return ret;
}
uint inv[300005],minv[300005],mul[300005];
void init()
{
inv[0]=inv[1]=minv[0]=minv[1]=mul[0]=mul[1]=1;
for(uint i=2;i<=300000;i++)
{
inv[i]=1ll*(mode-mode/i)*inv[mode%i]%mode;
minv[i]=1ll*minv[i-1]*inv[i]%mode;
mul[i]=1ll*mul[i-1]*i%mode;
}
}
uint MOD(uint x,uint y)
{
return x+y>=mode?x+y-mode:x+y;
}
uint to[(1<<20)+5];
uint n,a,b;
void NTT(uint *a,uint len,int k)
{
for(uint i=0;i<len;i++)if(i<to[i])swap(a[i],a[to[i]]);
for(uint i=1;i<len;i<<=1)
{
uint w0=pow_mul(3,(mode-1)/(i<<1));
for(uint j=0;j<len;j+=(i<<1))
{
uint w=1;
for(uint o=0;o<i;o++,w=1ll*w*w0%mode)
{
ll w1=a[j+o],w2=1ll*a[j+o+i]*w%mode;
a[j+o]=MOD(w1,w2)%mode,a[j+o+i]=MOD(mode-w2,w1);
}
}
}
if(k==-1)
{
uint inv=pow_mul(len,mode-2);
for(uint i=1;i<(len>>1);i++)swap(a[i],a[len-i]);
for(uint i=0;i<len;i++)a[i]=1ll*a[i]*inv%mode;
}
}
uint A[(1<<20)+5],B[(1<<20)+5],C[(1<<20)+5];
uint tempt[(1<<20)+5],tempf[(1<<20)+5],tempg[(1<<20)+5],tempG[(1<<20)+5],tempF[(1<<20)+5];
uint ret[(1<<20)+5];
void mult(uint *f,uint *g,uint len)
{
uint lim=1,l=0;
while(lim<=2*(len+1))lim<<=1,l++;
for(uint i=0;i<lim;i++)to[i]=((to[i>>1]>>1)|((i&1)<<(l-1)));
for(uint i=0;i<lim;i++)A[i]=B[i]=0;
for(uint i=0;i<=len;i++)A[i]=f[i],B[i]=g[i];
for(uint i=0;i<lim;i++)C[i]=0;
NTT(A,lim,1),NTT(B,lim,1);
for(uint i=0;i<lim;i++)C[i]=1ll*A[i]*B[i]%mode;
NTT(C,lim,-1);
}
void solve(uint *g,uint dep)
{
if(!dep){g[0]=1;return;}
if(dep==1)
{
g[0]=0,g[1]=1;
return;
}
if(dep&1)
{
solve(g,dep-1);
for(uint i=1;i<=dep;i++)tempG[i]=C[i-1];
for(uint i=0;i<dep;i++)tempG[i]=MOD(tempG[i],1ll*C[i]*(dep-1)%mode);
for(uint i=0;i<=dep;i++)g[i]=tempG[i];
}else
{
uint mid=(dep>>1);
solve(g,mid);
uint temp=1;
for(uint i=0;i<=mid;i++,temp=1ll*temp*mid%mode)tempg[i]=1ll*g[mid-i]*mul[mid-i]%mode,tempf[i]=1ll*temp*minv[i]%mode;
mult(tempg,tempf,mid);
for(uint i=0;i<=mid;i++)tempF[i]=1ll*C[mid-i]*minv[i]%mode;
mult(tempF,g,mid);
for(uint i=0;i<=dep;i++)g[i]=C[i];
}
}
uint get_C(uint x,uint y)
{
if(x<y)return 0;
return 1ll*mul[x]*minv[y]%mode*minv[x-y]%mode;
}
int main()
{
scanf("%u%u%u",&n,&a,&b);init();
solve(ret,n-1);
printf("%u\n",1ll*ret[a+b-2]*get_C(a+b-2,a-1)%mode);
return 0;
}
CF960G的更多相关文章
- 【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
[CF960G]Bandit Blues 题面 洛谷 题解 思路和这道题一模一样,这里仅仅阐述优化的方法. 看看答案是什么: \[ Ans=C(a+b-2,a-1)\centerdot s(n-1,a ...
- CF960G(第一类斯特林数)
题目 CF960G 做法 设\(f(i,j)\)为\(i\)个数的序列,有\(j\)个前缀最大值的方案数 我们考虑每次添一个最小数,则有:\(f(i,j)=f(i-1,j)+(i-1)*f(i-1,j ...
- [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个区间 ...
- CF960G Bandit Blues 分治+NTT(第一类斯特林数)
$ \color{#0066ff}{ 题目描述 }$ 给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大 ...
- CF960G Bandit Blues(第一类斯特林数)
传送门 可以去看看litble巨巨关于第一类斯特林数的总结 设\(f(i,j)\)为\(i\)个数的排列中有\(j\)个数是前缀最大数的方案数,枚举最小的数的位置,则有递推式\(f(i,j)=f(i- ...
- 【cf960G】G. Bandit Blues(第一类斯特林数)
传送门 题意: 现在有一个人分别从\(1,n\)两点出发,包中有一个物品价值一开始为\(0\),每遇到一个价值比包中物品高的就交换两个物品. 现在已知这个人从左边出发交换了\(a\)次,从右边出发交换 ...
随机推荐
- 自己写的java教程,免费分享
自己写的一套java教程,主要用于内部培训使用,有需要的可以直接免费下载: http://it.zhenzikj.com/download/java.zip 一共写了3套: java语言基础.网络开发 ...
- Springboot 和hutool文件上传下载
1.放开上传限制 servlet: multipart: enabled: true #默认支持文件上传 max-file-size: -1 #不做限制 max-request-size: -1 #不 ...
- Java- 基础知识脑图
- SpringCloudEureka上篇
SpringCloudEureka上篇 本文学习自<<重新定义SpringCloud>> Eureka简介 Eureka是Netflix公司开源的一款服务发现组件,该组件提供的 ...
- vscore 中 vim 常用快捷键
谷歌浏览器 ctrl + T 新建一个页面 ctrl + J 查看下载界面 F6 直接搜索 vscore 在 vscore 中使用 vim 建议去掉 ctrl 键的功能捆绑,不然会覆盖掉很多的 vsc ...
- aws note
Amazon EC2 Instance Types https://aws.amazon.com/ec2/instance-types/ My courses - AWS Skill Builder ...
- vue资料链接
vue 官方api:https://cn.vuejs.org/ vue资源精选:http://vue.awesometiny.com/ vue GitHub地址:https://github.com/ ...
- ROS创建工作空间 Create your workspace
https://blog.csdn.net/baidu_38869387/article/details/119840120 http://wiki.ros.org/catkin/Tutorials/ ...
- Py_excel
py_excel xlrd 读excel workbook = xlrd.open_workbook(file_path) sheet = workbook.sheet_by_name(sheet_n ...
- 【运维】Linux/Ec2挂载卷与NFS搭建实站讲解
英文Network File System(NFS),是由SUN公司研制的UNIX表示层协议(presentation layer protocol),能使使用者访问网络上别处的文件就像在使用自己的计 ...