CF960G-Bandit Blues【第一类斯特林数,分治,NTT】

正题

题目链接:https://www.luogu.com.cn/problem/CF960G


题目大意

求有多少个长度为nnn的排列,使得有AAA个前缀最大值和BBB个后缀最大值。

0≤n,A,B≤1050\leq n,A,B\leq 10^50n,A,B105


解题思路

显然的是把最大的数两边然后左边的是前缀最大值,右边的是前缀最小值。

然后考虑两个前缀最大值之间其实可以插任何数字,但是最大的一定要排在前面。

其实就是这些数字分成若干个圆排列的个数,就是第一类斯特林数。

枚举左右两边的数量就有
∑i=0n−1[ia−1][n−i−1b−1](n−1i)\sum_{i=0}^{n-1}\begin{bmatrix}i\\a-1\end{bmatrix}\begin{bmatrix}n-i-1\\b-1\end{bmatrix}\binom{n-1}{i}i=0n1[ia1][ni1b1](in1)
然后组合意义理解一下,我们可以考虑直接分成a+b−2a+b-2a+b2个环然后再依次排列到左右就是
[n−1a+b−2](a+b−2a−1)\begin{bmatrix}n-1\\a+b-2\end{bmatrix}\binom{a+b-2}{a-1}[n1a+b2](a1a+b2)

这个看起来就好做很多,先考虑怎么求第一类斯特林数。

考虑递推式
[nm]=[n−1m−1]+[n−1m]×(n−1)\begin{bmatrix}n\\m\end{bmatrix}=\begin{bmatrix}n-1\\m-1\end{bmatrix}+\begin{bmatrix}n-1\\m\end{bmatrix}\times(n-1)[nm]=[n1m1]+[n1m]×(n1)
可以理解为0∼n−10\sim n-10n1个里面选出mmm个数的乘积之和。

用生成函数做就是
∏i=0n−1(x+i)\prod_{i=0}^{n-1}(x+i)i=0n1(x+i)

用分治+NTTNTTNTT算就好了,当然推式子还有更快的方法

时间复杂度O(nlog⁡2n)O(n\log^2 n)O(nlog2n)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const ll N=4e5+10,P=998244353;
struct Poly{ll f[N];ll n;
}F[20];
ll n,a,b,f[N],g[N],r[N];bool use[20];
ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans;
}
void NTT(ll *f,ll n,ll op){for(ll i=0;i<n;i++)if(i<r[i])swap(f[i],f[r[i]]);for(ll p=2;p<=n;p<<=1){ll tmp=power(3,(P-1)/p),len=p>>1;if(op==-1)tmp=power(tmp,P-2);for(ll k=0;k<n;k+=p){ll buf=1;for(ll i=k;i<k+len;i++){ll tt=f[i+len]*buf%P;f[i+len]=(f[i]-tt+P)%P;f[i]=(f[i]+tt)%P;buf=buf*tmp%P;}}}if(op==-1){ll invn=power(n,P-2);for(ll i=0;i<n;i++)f[i]=f[i]*invn%P;}return;
}
void mul(Poly &x,Poly &y){ll n=1;while(n<x.n+y.n)n<<=1;for(ll i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)?(n>>1):0);for(ll i=0;i<n;i++)f[i]=x.f[i],g[i]=y.f[i];NTT(f,n,1);NTT(g,n,1);for(ll i=0;i<n;i++)f[i]=f[i]*g[i]%P;NTT(f,n,-1);for(ll i=0;i<n;i++)x.f[i]=f[i],y.f[i]=0;x.n=x.n+y.n-1;return;
}
ll FindE(){for(ll i=0;i<20;i++)if(!use[i])return i;
}
ll solve(ll l,ll r){if(l==r){ll p=FindE();F[p].f[0]=l;F[p].f[1]=1;F[p].n=2;use[p]=1;return p;}ll mid=(l+r)>>1;ll ls=solve(l,mid),rs=solve(mid+1,r);mul(F[ls],F[rs]);use[rs]=0;return ls;
}
ll C(ll n,ll m){ll ans=1,fac=1;for(ll i=m+1;i<=n;i++)ans=ans*i%P;for(ll i=1;i<=n-m;i++)fac=fac*i%P;return ans*power(fac,P-2)%P;
} 
signed main()
{scanf("%lld%lld%lld",&n,&a,&b);if(!a||!b||a+b-2>n-1)return puts("0")&0;if(n==1)return puts("1")&0;ll p=solve(0,n-2);printf("%lld\n",F[p].f[a+b-2]*C(a+b-2,a-1)%P);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

动态规划:openjudge 2.6-3532 最大上升子序列和 解题心得

传送门 题目描述 一个数的序列bi&#xff0c;当b1 < b2 < … < bS的时候&#xff0c;我们称这个序列是上升的。对于给定的一个序列(a1, a2, …,aN)&#xff0c;我们可以得到一些上升的子序列(ai1, ai2, …, aiK)&#xff0c;这里1 < i1 < i2 < … < iK…

边缘化搭建 DotNet Core 2.1 自动化发布和部署(下)

写在前面本篇文章是上一篇边缘化搭建 DotNet Core 2.1 自动化发布和部署(上)的后续操作&#xff0c;本文主要讲解如何开启Docker Remote API&#xff0c;开启Remote API后的权限安全问题。配置Jenkins构建项目&#xff0c;并在云服务器上构建成功。废话不多说&#xff0c;我们一…

牛客题霸 [二进制中1的个数] C++题解/答案

牛客题霸 [二进制中1的个数] C题解/答案 题目描述 输入一个整数&#xff0c;输出该数32位二进制表示中1的个数。其中负数用补码表示。 题解&#xff1a; 判断1的个数 x&(-x)2^k 有点类似于树状数组中lowbit的操作 代码&#xff1a; class Solution { public:int Num…

2021牛客暑期多校训练营5 G-Greater Integer, Better LCM(暴力+子集dp)

G-Greater Integer, Better LCM 看到校大佬的代码就瞬间会做了。 当时和队友想的是&#xff0c;首先转化题意即找两个数x≥a,y≥b[lcm(a,b)c]x\ge a,y\ge b[\text{lcm}(a,b)c]x≥a,y≥b[lcm(a,b)c]&#xff0c;首先不考虑x≥a,y≥bx\ge a,y\ge bx≥a,y≥b的限制&#xff0c;显…

P2179-[NOI2012]骑行川藏【导数,二分】

正题 题目链接:https://www.luogu.com.cn/problem/P2179 题目大意 给出EEE和nnn个si,ki,uis_i,k_i,u_isi​,ki​,ui​求一个序列viv_ivi​满足 ∑i1nkisi(vi−ui)2≤E\sum_{i1}^nk_is_i(v_i-u_i)^2\leq Ei1∑n​ki​si​(vi​−ui​)2≤E 的情况下最小化 ∑i1nsivi\sum_{i1}^…

不止代码:乘法游戏 题解(区间dp)

题目描述 乘法游戏是在一行牌上进行的。每一张牌包括了一个正整数。在每一个移动中&#xff0c;玩家拿出一张牌&#xff0c;得分是用它的数字乘以它左边和右边的数&#xff0c;所以不允许拿第1张和最后1张牌。最后一次移动后&#xff0c;这里只剩下两张牌。 你的目标是使得分的…

边缘化搭建DotNet Core 2.1 自动化构建和部署环境(上)

写在前面写这篇文章的缘由是由于笔者的对新兴技术方向有所追求&#xff0c;但个人资产有限&#xff0c;只能容许购买一台阿里云低配1核2G服务器。服务器上搭建了 Centos7 & Docker & Jenkins & ASP.NET Core 2.0 自动化发布和部署 环境后牺牲了大部分性能。造成了一…

牛客题霸 [丑数] C++题解/答案

牛客题霸 [丑数] C题解/答案 题目描述 把只包含质因子2、3和5的数称作丑数&#xff08;Ugly Number&#xff09;。例如6、8都是丑数&#xff0c;但14不是&#xff0c;因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 题解&#xff1a;…

codeforces1549 F1 - Gregor and the Odd Cows (Easy)(皮克公式)

皮克公式&#xff1a;求格点多边形面积 AB2I−1A\frac B 2I-1 A2B​I−1 其中 A&#xff1a;area 面积 B&#xff1a;boundary 边界上整点的个数 I&#xff1a;interior 多边形内部点的个数 对于两个整数点(x1,y1),(x2,y2)(x_1,y_1),(x_2,y_2)(x1​,y1​),(x2​,y2​)来说&…

P3288-[SCOI2014]方伯伯运椰子【0/1分数规划,负环】

正题 题目链接:https://www.luogu.com.cn/problem/P3288 题目大意 给出nnn个点mmm条边的一张图&#xff0c;没条边iii流量为cic_ici​&#xff0c;费用是did_idi​&#xff0c;然后缩小一个流量费用是aia_iai​&#xff0c;增加一个流量费用是bib_ibi​。 要求改动图之后最大…

不止代码:ybtoj-消除木块(区间DP)

题目描述 n个木块排成一列&#xff0c;每个木块都有一个颜色。 每次&#xff0c;你都可以点击一个木块&#xff0c;这样被点击的木块以及和它相邻并且同色的木块就会消除。 如果一次性消除了k个木块&#xff0c;那么就会得到k*k分。 给定你一个游戏初始状态&#xff0c;请你…

.NET Core实战项目之CMS 第六章 入门篇-Vue的快速入门及其使用

写在前面上面文章我给大家介绍了Dapper这个ORM框架的简单使用&#xff0c;大伙会用了嘛&#xff01;本来今天这篇文章是要讲Vue的快速入门的&#xff0c;原因是想在后面的文章中使用Vue进行这个CMS系统的后台管理界面的实现。但是奈何Vue实现的SPA有一定的门槛&#xff0c;不太…

牛客练习赛10 F-序列查询(莫队+链表)

F-序列查询 v5zsq题解 假设数字xxx在区间[l,r]种出现y次&#xff0c;那么包含x的子区间个数为2r−l1−y⋅(2y−1)2^{r-l1-y}(2^y-1)2r−l1−y⋅(2y−1)&#xff0c;因此对询问贡献是x⋅2r−l1−y⋅(2y−1)x[2r−l1−2r−l1−y]x2^{r-l1-y}(2^y-1)x[2^{r-l1}-2^{r-l1-y}]x⋅2r…

牛客题霸 [有关阶乘的两个问题1] C++题解/答案

牛客题霸 [有关阶乘的两个问题1] C题解/答案 题目描述 给定一个非负整数N&#xff0c;返回N!结果的末尾为0的数量 题解&#xff1a; 这个题有技巧 102*5,也就是说有一对2和5就会贡献一个0&#xff0c;但是2的数量远远大于5&#xff0c;所以只用统计五即可 代码&#xff1a…

不止代码:ybtoj-棋盘分割(二维区间dp)

题目描述 将一个8*8的棋盘进行如下分割&#xff1a;将原棋盘割下一块矩形棋盘并使剩下部分也是矩形&#xff0c;再将剩下的部分继续如此分割&#xff0c;这样割了n-1次后&#xff0c;连同最后剩下的矩形棋盘共有n块矩形棋盘。 (每次切割都只能沿着棋盘格子的边进行) 原棋盘上…

P7717-「EZEC-10」序列【Trie】

正题 题目链接:https://www.luogu.com.cn/problem/P7717 题目大意 求有多少个长度为nnn的序列aaa满足&#xff0c;都在[0,k][0,k][0,k]的范围内且满足mmm个限制刑如&#xff1a;axxorayza_x\ xor\ a_yzax​ xor ay​z 0≤n,m≤5105,0≤k<2300\leq n,m\leq 5\times 10^5,0\…

ASP.NET Core MVC 授权的扩展:自定义 Authorize 和 IApplicationModelProvide

一、概述ASP.NET Core MVC 提供了基于角色( Role )、声明( Chaim ) 和策略 ( Policy ) 等的授权方式。在实际应用中&#xff0c;可能采用部门&#xff08; Department , 本文采用用户组 Group &#xff09;、职位 ( 可继续沿用 Role )、权限( Permission )的方式进行授权。要达…

牛客题霸 [分糖果问题] C++题解/答案

牛客题霸 [分糖果问题] C题解/答案 题目描述 一群孩子做游戏&#xff0c;现在请你根据游戏得分来发糖果&#xff0c;要求如下&#xff1a; 每个孩子不管得分多少&#xff0c;起码分到一个糖果。任意两个相邻的孩子之间&#xff0c;得分较多的孩子必须拿多一些糖果。(若相同则…

不止代码 洛谷P1006 传纸条(dp)

传送门 走两次 dp[x1][y1][x2][y2]表示两条路分别到两个点的坐标后的最大值 为了防止走重&#xff0c;dp[x1][y1][x1][y1]赋值为无穷小 时间复杂度O&#xff08;n^4&#xff09; 代码 #include<cstdio> #include<cstring> #include<algorithm> #include<…

通俗易懂,C#如何安全、高效地玩转任何种类的内存之Span

前言作为.net程序员&#xff0c;使用过指针&#xff0c;写过不安全代码吗&#xff1f;为什么要使用指针&#xff0c;什么时候需要使用它&#xff1f;如果能很好地回答这两个问题&#xff0c;那么就能很好地理解今天了主题了。C#构建了一个托管世界&#xff0c;在这个世界里&…