zoukankan      html  css  js  c++  java
  • CodeForces 960G. Bandit Blues

    题目简述:求满足如下条件的$N leq 10^5$排列的个数(模$998244353$):

    1. 从左往右会依次遇到$A$个比当前遇到的最大值更大的元素;

    2. 从右往左会依次遇到$B$个比当前遇到的最大值更大的元素。

    解:code

    不管是从左往右,还是从右往左,我们都会遇到最大值$N$,并且此后不会再遇到比$N$更大的元素。

    对任何一个满足条件的排列,我们先找到元素$N$的位置$p$,于是元素$N$将排列分成左右两个部分。

    设左半部分遇到的$A$个比当前遇到的最大值更大的元素依次位于$i_1, i_2, dots, i_A$,特别地$i_1 = 1, i_A = p$。则$[i_1, i_2), [i_2, i_3), dots, [i_{A-1}, i_A)$这$A-1$个部分是一个圆排列(或者可以看成一个轮换),其代表元是该部分的最大值(因为最大值永远在第一个)。这相当于是将$p-1$个元素分成$A-1$个圆排列。

    同样的,右半部分相当于是将$N-p-1$个元素分成$B-1$个圆排列。

    总的说来,我们需要把$N-1$个元素分成$A+B-2$个圆排列,其方案数是第一类斯特林数

    $$ egin{bmatrix} N-1 \ A+B-2 end{bmatrix}, $$

    而后从$A+B-2$个圆排列中选出$A-1$个放在左边,而剩下的放在右边,其选法数为

    $$ inom{A+B-2}{A-1}. $$

    从而所求答案为

    $$ inom{A+B-2}{A-1} egin{bmatrix} N-1 \ A+B-2 end{bmatrix}. $$

    而求斯特林数的方法参见这里,用分治以及快速傅里叶变换,可在$O(n log n)$复杂度内求得。注意到此题的模数可以用快速数论变换(Fast Number Theory Transform)来做。

    而对于组合数,则需要计算模的逆元。

  • 相关阅读:
    Python随笔之字典Dict
    Python随笔之列表List
    Python基础整理,懒得分类了,大家对付看看吧
    shell批量推送公钥脚本
    Xcode 切换target 之后打包失败
    百度导航sdk错误日志
    前端项目中去掉替换双引号
    taro3.x项目中引用taro-ui以及taro-iconfont-cli
    taro
    JS中some() every() forEach() map() filter()的区别
  • 原文地址:https://www.cnblogs.com/TinyWong/p/10438986.html
Copyright © 2011-2022 走看看