题目大意:

  求满足比之前的任何数小的有A个,比之后的任何数小的有B个的长度为n的排列个数。

题目分析:

  首先写出递推式,设s(n,k)表示长度为n的排列,比之前的数小的数有k个。

  我们假设新加入的数为1,那么s(n,k)=s(n-1,k-1)+(n-1)*s(n,k)。

  这个式子是第一类斯特林数的递推式。

  用h(n,a,b)表示满足题目给出条件的排列个数。

  得出h(n,a,b)=Σs(k,a-1)*s(n-k-1,b-1)*C(n-1,k)。直观的理解就是将原排列从最高点分成两部分,两部分分别组合然后乘起来。

  这样我们发现h(n,a,b)=s(n-1,a+b-2)*C(a+b-2,a-1)。这实际上就是给出一个a+b-2的排列,然后选出其中需要的点放到右边,我们不用考虑多余的点,因为它们的排列已经被计算。

  由于无符号第一类斯特林数对应着升幂的系数,构造x(x+1)(x+2)...(x+n-1),它的x^k的系数等于s(n,k)的值,由于最高项系数为1,所以分治FFT。

代码:

  

 #include<bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std; const int mod = ;
const int gg = ; int n,a,b; vector<int> res[]; int up[]; int ord[]; int fast_pow(int now,int pw){
if(pw == ) return ;
if(pw == ) return now;
int z = fast_pow(now,pw/);
z = (1ll*z*z)%mod;
if(pw & ){z= (1ll*z*now)%mod;}
return z;
} void fft(int now,int len,int f){
for(int i=;i<len;i++) if(i<ord[i]) swap(res[now][i],res[now][ord[i]]);
for(int i=;i<len;i<<=){
int wn = fast_pow(gg,(mod-)/(i<<));
if(f == -) wn = fast_pow(wn,mod-);
for(int j=;j<len;j+=(i<<)){
for(int k=,w=;k<i;k++,w = (1ll*w*wn)%mod){
int x = res[now][j+k],y = (1ll*w*res[now][j+k+i])%mod;
res[now][j+k] = (x+y)%mod;
res[now][j+k+i] = (x-y+mod)%mod;
}
}
}
if(f == -){
int iv = fast_pow(len,mod-);
for(int i=;i<len;i++) res[now][i] = (1ll*res[now][i]*iv)%mod;
}
} void multi(int p1,int p2){
int n1 = res[p1].size()-,n2 = res[p2].size()-;
int len = ,om = ;
while(len <= (n1+n2+))len<<=,om++;
for(int i=n1+;i<len;i++) res[p1].push_back();
for(int i=n2+;i<len;i++) res[p2].push_back();
for(int i=;i<len;i++) ord[i] = (ord[i>>]>>)+((i&)<<om-);
fft(p1,len,);fft(p2,len,);
for(int i=;i<len;i++){
res[p1][i] = (1ll*res[p1][i]*res[p2][i])%mod;
if(res[p1][i] < ) res[p1][i]+=mod;
}
fft(p1,len,-);
res[p2].clear();
} void divide(int l,int r,int now){
if(l == r) {up[now] = l;return;}
int mid = (l+r)/;
divide(l,mid,now<<);
divide(mid+,r,now<<|);
multi(up[now<<],up[now<<|]);
up[now] = up[now<<];
} void work(){
if(a == || b == ){puts("");return;}
if(n == ){if(a+b==)puts(""); else puts(""); return;}
int c = ;
if(a<b) swap(a,b);
if(a- > a+b-) c = ;
for(int i=;i<=a-;i++){
c = (1ll*c*(a+b--i))%mod;
c = (1ll*c*fast_pow(i,mod-))%mod;
}
for(int i=;i<n;i++) res[i].push_back(i-),res[i].push_back();
divide(,n-,);
c = (1ll*c*res[up[]][a+b-])%mod;
printf("%d",c);
} int main(){
scanf("%d%d%d",&n,&a,&b);
work();
return ;
}

Codeforces960G Bandit Blues 【斯特林数】【FFT】的更多相关文章

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

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

  2. codeforces960G. Bandit Blues

    题目链接:codeforces960G 来看看三倍经验:hdu4372 luogu4609 某蒟蒻的关于第一类斯特林数的一点理解QAQ:https://www.cnblogs.com/zhou2003 ...

  3. 【xsy1301】 原题的价值 组合数+斯特林数+FFT

    题目大意:求$n\times2^{\frac{(n-1)(n-2)/2}{2}}\sum\limits_{i=0}^{n-1}\dbinom{n-1}{i}i^k$ 数据范围:$n≤10^9$,$k≤ ...

  4. CF960G Bandit Blues 第一类斯特林数+分治+FFT

    题目传送门 https://codeforces.com/contest/960/problem/G 题解 首先整个排列的最大值一定是 \(A\) 个前缀最大值的最后一个,也是 \(B\) 个后缀最大 ...

  5. CF960G Bandit Blues 【第一类斯特林数 + 分治NTT】

    题目链接 CF960G 题解 同FJOI2016只不过数据范围变大了 考虑如何预处理第一类斯特林数 性质 \[x^{\overline{n}} = \sum\limits_{i = 0}^{n}\be ...

  6. CF960G Bandit Blues(第一类斯特林数)

    传送门 可以去看看litble巨巨关于第一类斯特林数的总结 设\(f(i,j)\)为\(i\)个数的排列中有\(j\)个数是前缀最大数的方案数,枚举最小的数的位置,则有递推式\(f(i,j)=f(i- ...

  7. CF960G Bandit Blues 第一类斯特林数、NTT、分治/倍增

    传送门 弱化版:FJOI2016 建筑师 由上面一题得到我们需要求的是\(\begin{bmatrix} N - 1 \\ A + B - 2 \end{bmatrix} \times \binom ...

  8. CF960G Bandit Blues 分治+NTT(第一类斯特林数)

    $ \color{#0066ff}{ 题目描述 }$ 给你三个正整数 \(n\),\(a\),\(b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大 ...

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

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

随机推荐

  1. 11-51单片机ESP8266学习-AT指令(ESP8266作为TCP客户端,连接TCP服务器,用串口调试助手和手机TCP调试助手测试)

    写完题目刚想起来一件事情,如果手机作为客户端(不连接路由器的情况下),手机连接模块的无线会分配一个IP地址,,,这个IP地址事先我也不知道....我先看看AT指令里面有没有一个指令可以打印一下连接自己 ...

  2. XML转换为对象/Javabean

    將XML轉換為對象 /** * xml转换成JavaBean * @param xml * @param c * @return */ public static <T> T conver ...

  3. Vue-父子组件传值

    在 Vue 中,父子组件的关系可以总结为 prop 向下传递,事件向上传递.一.父组件向子组件传值 使用 Prop 传递数据,父组件的数据需要通过 prop 才能下发到子组件中,子组件要显式地用 pr ...

  4. [转]The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

    完整错误信息: THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS"AS IS" AND ANY ...

  5. LOJ #559. 「LibreOJ Round #9」ZQC 的迷宫

    一道ZZ结论题,主要是来写一写交互题的. 我们要先知道一句话: 扶着墙是肯定可以走出简单迷宫的. 然后我们冷静分析问题.若这个迷宫是\(n\times m\)的,那么最多有\(2mn+n+m\)个墙壁 ...

  6. Duplicate entry * for key *

    一.问题 插入数据时报错 Duplicate entry * for key * 二.分析 建表语句 CREATE TABLE `t_product_result_config` ( `id` var ...

  7. 在Windows7上如何找到Cookie

    摘要 出于兴趣爱好,前一阵子做了一个网页,网页中需要用到Cookie,但是,根据书上的说明,并没有找打教材中所说的Cookie的位置,本文就主要介绍在计算机(Win7)中Cookie的存放位置,同样适 ...

  8. 大话重构连载15:采用Mock技术完成测试

    第五次重构我们引入了数据库的设计,用户信息要从数据库中读取,问候语库存储在数据库中,并支持添加与更新.数据库的引入使自动化测试变得困难了,因为数据状态总是变化着的,而这种变化使得测试过程不能复现,这是 ...

  9. React.js 开发参见问题 Q&A

    文章中我整理了 React.js 开发过程中一些参见问题的解答汇总,供大家参考. 1. 一些课程资源 课程完整的思维导图请查考文章:React.js 入门与实战课程思维导图,我使用的思维导图软件是 M ...

  10. CAD2020下载安装AutoCAD2020中文版下载地址+安装教程

    AutoCAD2020中文版为目前最新软件版本,我第一时间拿到软件进行安装测试,确保软件正常安装且各项功能正常可以使用,立刻拿出来分享,想用最新版本的话,抓紧下载使用吧: 我把我用的安装包贡献给你下载 ...