题目链接:codeforces960G

来看看三倍经验:hdu4372 luogu4609

某蒟蒻的关于第一类斯特林数的一点理解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)\)表示第一类斯特林数

这样你就可以完成后两题了

那么对于第一题呢?我们有这个式子:

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

于是分治+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的更多相关文章

  1. Codeforces960G Bandit Blues 【斯特林数】【FFT】

    题目大意: 求满足比之前的任何数小的有A个,比之后的任何数小的有B个的长度为n的排列个数. 题目分析: 首先写出递推式,设s(n,k)表示长度为n的排列,比之前的数小的数有k个. 我们假设新加入的数为 ...

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

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

  3. 【CF960G】Bandit Blues

    [CF960G]Bandit Blues 题面 洛谷 题解 思路和这道题一模一样,这里仅仅阐述优化的方法. 看看答案是什么: \[ Ans=C(a+b-2,a-1)\centerdot s(n-1,a ...

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

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

  5. [CF960G] Bandit Blues

    题意 给你三个正整数 \(n,a,b\),定义 \(A\) 为一个排列中是前缀最大值的数的个数,定义 \(B\) 为一个排列中是后缀最大值的数的个数,求长度为 \(n\) 的排列中满足 \(A = a ...

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

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

  7. 解题:CF960G Bandit Blues & FJOI 2016 建筑师

    题面1 题面2 两个题推导是一样的,具体实现不一样,所以写一起了,以FJOI 2016 建筑师 的题面为标准 前后在组合意义下一样,现在只考虑前面,可以发现看到的这a个建筑将这一段划分成了a-1个区间 ...

  8. Codeforces 960G. Bandit Blues

    Description 你需要构造一个长度为 \(n\) 的排列 , 使得一个数作为前缀最大值的次数为 \(A\) , 作为后缀最大值的次数为 \(B\) , 求满足要求的排列个数 . 题面 Solu ...

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

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

随机推荐

  1. 【转】Redis一般会遇到的问题以及解析

    单线程的 Redis 为什么这么快 这个问题是对 Redis 内部机制的一个考察.根据我的面试经验,很多人都不知道Redis 是单线程工作模型.所以,这个问题还是应该要复习一下的. 回答主要是以下三点 ...

  2. hive基本操作与应用

    通过hadoop上的hive完成WordCount 启动hadoop Hdfs上创建文件夹 上传文件至hdfs 启动Hive 创建原始文档表 导入文件内容到表docs并查看 用HQL进行词频统计,结果 ...

  3. 原生js实例对象方法

    Array中的方法 ☞ toString() // 把数组转换为字符串,使用逗号分隔☞ valueOf() // 返回数组对象本身 ☞ 栈方法(先进后出)ary.push() // 该方法有一个返回值 ...

  4. 从0开始的Python学习014面向对象编程

     简介 到目前为止,我们的编程都是根据数据的函数和语句块来设计的,面向过程的编程.还有一种我们将数据和功能结合起来使用对象的形式,使用它里面的数据和方法这种方法叫做面向对象的编程. 类和对象是面向对象 ...

  5. row_number() over()分页查询

    1.首先讲下row_number() over() 是干什么的? 是一个分析函数,会在数据表生成一个排序列. 案例SQL: select ROW_NUMBER() over(order by book ...

  6. 关于MySQL集群的一些看法

    作者:Gary Chen链接:https://zhuanlan.zhihu.com/p/20204156来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 市面上的招聘往往 ...

  7. JSX有感

    开发一个网页,我们要写视图部分HTML,也要写交互逻辑JS. 写JS时,不断翻看HTML,确保querySelector能取到期望的元素. 改HTML时,一个个排查JS文件,确保其没受影响. -- 类 ...

  8. vue笔记未整理

    全局组件 局部组件 子组件传值到父组件 父子组件传值 watch跟计算属性差不多,都会有缓存,计算属性优先 计算属性get set 对象 数组 对象 数组 不复用 改变数组 直接修改数组,页面没变化 ...

  9. CentOS 安装 ceph 单机版(luminous版本)

    一.环境准备 CentOS Linux release 7.4.1708 (Core)一台,4块磁盘(sda.sdb,.sdc.sdd) 192.168.27.130 nceph 二.配置环境 1.修 ...

  10. C# 中利用 CRC32 值判断文件是否重复

    需要在 NuGet 中引用 Crc32.NET 包 直接贴代码了: using Force.Crc32; using System; using System.Collections.Generic; ...