打表可以发现相当于不存在长度>=3的递减子序列。

  考虑枚举在哪一位第一次不卡限制。注意到该位一定会作为前缀最大值。判掉已确定位不合法的情况后,现在的问题即为求长度为i、首位>j的合法排列个数,设其为g[i][j]。

  由于首位>j,1~j在排列中一定依次出现,并且在j出现之前,>j的部分也一定单增。于是可以先将>j的部分安排好,再将1~j不改变相对顺序地插入。>j的部分即是考虑没有各种奇怪的限制要怎么求。设f[i][j]为长度i的排列,第一个非前缀max的数在j位置的方案数。特别地,令f[i][i+1]为不存在这样的数时的方案数(当然就是1)。则有f[i][j]=Σf[i-1][k] (j-1<=k<=i+1),也即f[i][j]=f[i][j+1]+f[i-1][j-1]。这样f[i][1~i+1]即为n=i且无限制的答案,并且有了这个求g就很容易了,即考虑1~j的插入位置,有g[i][j]=Σf[i-j][k]·C(j+k-2,k-2) (k=2~i-j+1)。于是得到了一个80分的做法。给无限制时的答案打一下表又可以发现答案即为卡特兰数,可以再拿4分。

  似乎有点陷入僵局。继续打表!我们惊奇的发现,g[i][j]=f[i+1][j+3]。这个式子可能是说明之前绕了太多弯,本来直接考虑怎么推g就行了,虽然这个我没想清楚也懒得考虑了。由于最终要用到的只是g中的n项,如果能快速求出f数组中任意项,问题就解决了。

  考虑根据f的转移方程画一张有向图,答案即为由原点走到目标点的路径条数。

得到这样一个丑陋的图。如果要到最左的点,就是卡特兰数的经典模型。于是下面所有的分析只要类比卡特兰数就可以了。事实上这是个原题https://www.luogu.org/problemnew/show/P1641。

  考虑先不管图的边界随便走,此时向右下走n步、向左走m步时的方案数显然是C(n+m,m)。加上边界后,考虑哪些走法会变得不合法,显然不合法的方案中一定存在一个第一次跨过边界的点,而这可以看做是从左上一个并不存在的点(原点向左平移两格)、以边界为对称轴、按和右边对称的走法走来的,经过此点后走法变为和右边相同。并且显然每一种从这个不存在的点到达终点的走法都对应于一种不合法方案。两个组合数相减即可。原问题也被线性解决了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
#define ll long long
#define P 998244353
#define N 600010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<''||c>'')) c=getchar();return c;}
int gcd(int n,int m){return m==?n:gcd(m,n%m);}
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
int T,n,a[N],fac[N<<],inv[N<<],mn[N],ans;
int C(int n,int m){if (m<) return ;return 1ll*fac[n]*inv[m]%P*inv[n-m]%P;}
int calc(int n,int m){m=n-m;return (C(n+m,m)-C(n+m,m-)+P)%P;}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj5416.in","r",stdin);
freopen("bzoj5416.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
T=read();
while (T--)
{
n=read();
for (int i=;i<=n;i++) a[i]=read();
fac[]=;for (int i=;i<=*n;i++) fac[i]=1ll*fac[i-]*i%P;
inv[]=inv[]=;for (int i=;i<=*n;i++) inv[i]=P-1ll*(P/i)*inv[P%i]%P;
for (int i=;i<=*n;i++) inv[i]=1ll*inv[i-]*inv[i]%P;
int mx=;ans=;
mn[n+]=n+;
for (int i=n;i>=;i--) mn[i]=min(mn[i+],a[i]);
for (int i=;i<=n;i++)
{
mx=max(mx,a[i]);
ans=(ans+calc(n-i+,mx-i+))%P;
if (a[i]<mx&&a[i]>mn[i+]) break;
}
printf("%d\n",ans);
}
return ;
}

BZOJ5416 NOI2018冒泡排序(动态规划+组合数学)的更多相关文章

  1. BZOJ_5416_[Noi2018]冒泡排序_DP+组合数+树状数组

    BZOJ_5416_[Noi2018]冒泡排序_DP+组合数+树状数组 Description www.lydsy.com/JudgeOnline/upload/noi2018day1.pdf 好题. ...

  2. 【洛谷4769】[NOI2018] 冒泡排序(动态规划_组合数学)

    题目: 洛谷 4769 博客页面左下角的嘴嘴瓜封神之战中的题目 分析: 一个排列交换次数为 \(\frac{1}{2}\sum_{i=1}^{n}|i-p_i|\) 的充要条件是这个排列不存在长度为 ...

  3. [NOI2018]冒泡排序

    https://www.zybuluo.com/ysner/note/1261482 题面 戳我 \(8pts\ n\leq9\) \(44pts\ n\leq18\) \(ex12pts\ q_i= ...

  4. 【NOI 2018】冒泡排序(组合数学)

    题意大概是给定一个长度为$n$的排列$p$,求有多少长度为$n$的排列满足冒泡排序的交换次数为$\frac{1}{2} \sum\limits_{i = 1}^{n}|i - p_{i}|$. 可以发 ...

  5. [POJ1664] 放苹果 (动态规划,组合数学)

    题目描述 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分发(5,1,1和1,1,5是同一种方法) 输入输出格式 输入格式: 第一行是测试数据的数目t(0 <= ...

  6. 【UOJ#394】[NOI2018] 冒泡排序

    题目链接 题意 求有多少个字典序严格大于给定排列 \(q_i\) 的排列满足其逆序对数(冒泡排序需要交换的次数)达到下限 \(\frac{1}{2}\sum_{i=1}^n |i-p_i|\) Sol ...

  7. luogu P4769 [NOI2018]冒泡排序 结论 树状数组 卡特兰数

    LINK:冒泡排序 神题. 可以想到爆搜 期望得分5~10分. 打成这个样子心态不得爆炸? 仔细分析 一个不合法序列还有什么标志. 容易想到某个数字离自己位置相反的方向多走了一步. 考虑单独对每个数字 ...

  8. Codeforces 979E Kuro and Topological Parity - 动态规划 - 组合数学

    题目传送门 传送点 题目大意 给定$n$个标号依次为$1, 2, \cdots, n$的点,其中一些点被染成一些颜色,剩下的点没有染色.你需要添加一些有向边并将剩下的点染色,满足有向边从编号小的一端指 ...

  9. BZOJ2339 HNOI2011卡农(动态规划+组合数学)

    考虑有序选择各子集,最后除以m!即可.设f[i]为选i个子集的合法方案数. 对f[i]考虑容斥,先只满足所有元素出现次数为偶数.确定前i-1个子集后第i个子集是确定的,那么方案数为A(2n-1,i-1 ...

随机推荐

  1. $Luogu P2029$ 跳舞 题解

    一道不是十分水的\(dp\). 首先我们考虑\(dp\)方程的构造.起初我定义的状态是\(dp_{i,j}\)表示前\(i\)个格子,总共跳了\(j\)次的最大得分.但事实上它并不可以转移,因为我们不 ...

  2. 添加静态路由 route add -host 子网掩码 -- 在线解析

    1.215        -----       R(172.16.0.1)      <--------- gw(61.146.164.109) |                       ...

  3. jquery操作checked

    jquery操作checkbox,如何获取勾选状态?如何使得勾选?如何取消勾选? 来段代码就知道了: <html> <head> <meta charset=" ...

  4. Android开发——异步任务中Activity销毁时的问题

    0.  前言 在Android开发中经常会发生Activity的销毁重建,比如用户长时间接听一个电话后回到APP.在Android开发--Fragment知识整理(二)中我们提到了使用Fragment ...

  5. [BZOJ4144][AMPPZ2014]Petrol[多源最短路+MST]

    题意 题目链接 分析 假设在 \(a \rightarrow b\) 的最短路径中出现了一个点 \(x\) 满足到 \(x\) 最近的点是 \(c\) ,那么我们完全可以从 \(a\) 直接走到 \( ...

  6. Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI

    目录 引言 Search APIs Search API Search Request 可选参数 使用 SearchSourceBuilder 构建查询条件 指定排序 高亮请求 聚合请求 建议请求 R ...

  7. SQL Server 全文搜索

    SQL Server 的全文搜索(Full-Text Search)是基于分词的文本检索功能,依赖于全文索引.全文索引不同于传统的平衡树(B-Tree)索引和列存储索引,它是由数据表构成的,称作倒转索 ...

  8. REST-framework快速构建API--权限

    我们在访问资源时,有些资源保密程度较高,需要特殊的人员才能访问.比如,获取公司的每日收入流水的API接口,只能CEO才能查看. 这时,我们就需要将资源设定权限了. REST-framework实现如下 ...

  9. index索引的一些简单理解

    index索引(普通索引,允许出现相同的索引内容) 1.索引 索引是在数据量和访问量较大的时候,而出现的一种优化数据库的手段 索引可以提高查询(select)的效率,但相应的,它的 INSERT 与 ...

  10. 【Alpha】第七次Scrum meeting

    今日任务一览: 姓名 今日完成任务 所耗时间 刘乾 今日没有做很多事...一天都在沟通细化需求与画电路图 2 鲁聃 生成物理报告实验页面的生成 Issue链接:https://github.com/b ...