原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ394.html

题解

首先我们发现一个数不能既被往左换又被往右换。也就是说不能有任何一个数左边有比他大的,又被有比他小的。

也就是最长下降子序列长度不超过 2 。

所以我们一定可以找到 2 个上升序列包含所有的数。

于是容易想到 $O(n^2)$ 的 dp:

$dp_{i,j}$ 表示加入了 $i$ 个数,最大值为 $j$ 的情况下,填完的方案数。

那么,如果下一个数小于 $i$ ,那肯定是填小于 $j$ 的第一个,否则就是填一个比 $j$ 更大的值。

我们把这个东西看做括号序列,填一个比 $j$ 大的值就相当于加入若干个左括号,然后再加入一个右括号;填一个比 $j$ 小的数字就相当于加入一个右括号。

这个东西的方案数可以用类似于卡特兰数的公式 $C_i = \binom {2i} {i} - \binom {2i} {i-1}$ 的推导方法来得到。

这个请自行搜索,懒得画图了。

代码

  1. #pragma GCC optimize("Ofast","inline")
  2. #include <bits/stdc++.h>
  3. #define clr(x) memset(x,0,sizeof (x))
  4. #define For(i,a,b) for (int i=a;i<=b;i++)
  5. #define Fod(i,b,a) for (int i=b;i>=a;i--)
  6. #define pb push_back
  7. #define mp make_pair
  8. #define fi first
  9. #define se second
  10. #define _SEED_ ('C'+'L'+'Y'+'A'+'K'+'I'+'O'+'I')
  11. #define outval(x) printf(#x" = %d\n",x)
  12. #define outvec(x) printf("vec "#x" = ");for (auto _v : x)printf("%d ",_v);puts("")
  13. #define outtag(x) puts("----------"#x"----------")
  14. #define outarr(a,L,R) printf(#a"[%d...%d] = ",L,R);\
  15. For(_v2,L,R)printf("%d ",a[_v2]);puts("");
  16. using namespace std;
  17. typedef long long LL;
  18. LL read(){
  19. LL x=0,f=0;
  20. char ch=getchar();
  21. while (!isdigit(ch))
  22. f|=ch=='-',ch=getchar();
  23. while (isdigit(ch))
  24. x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
  25. return f?-x:x;
  26. }
  27. const int N=1200005,mod=998244353;
  28. void Add(int &x,int y){
  29. if ((x+=y)>=mod)
  30. x-=mod;
  31. }
  32. void Del(int &x,int y){
  33. if ((x-=y)<0)
  34. x+=mod;
  35. }
  36. int Pow(int x,int y){
  37. int ans=1;
  38. for (;y;y>>=1,x=(LL)x*x%mod)
  39. if (y&1)
  40. ans=(LL)ans*x%mod;
  41. return ans;
  42. }
  43. int n;
  44. int Fac[N],Inv[N];
  45. void prework(){
  46. int n=N-1;
  47. for (int i=Fac[0]=1;i<=n;i++)
  48. Fac[i]=(LL)Fac[i-1]*i%mod;
  49. Inv[n]=Pow(Fac[n],mod-2);
  50. Fod(i,n,1)
  51. Inv[i-1]=(LL)Inv[i]*i%mod;
  52. }
  53. int C(int n,int m){
  54. if (m>n||m<0)
  55. return 0;
  56. return (LL)Fac[n]*Inv[m]%mod*Inv[n-m]%mod;
  57. }
  58. int p[N];
  59. int q[N],head,tail;
  60. int pos,vis[N];
  61. int calc(int x,int y){
  62. //from (x,y) to (n,n)
  63. //without crossing line x=y
  64. if (x>n||y>n)
  65. return 0;
  66. assert(x<=y);
  67. int _x=y+1,_y=x-1;
  68. return (C(n-x+n-y,n-x)-C(n-_x+n-_y,n-_x)+mod)%mod;
  69. }
  70. void Main(){
  71. n=read();
  72. For(i,1,n)
  73. p[i]=read();
  74. int ans=0;
  75. clr(vis);
  76. pos=1,head=tail=0;
  77. int Mx=0;
  78. int x=0,y=0;
  79. For(i,1,n){
  80. if (p[i]>Mx){
  81. Mx=p[i];
  82. while (pos<p[i]){
  83. if (!vis[pos]){
  84. q[++tail]=pos;
  85. vis[pos]=1;
  86. y++;
  87. }
  88. pos++;
  89. }
  90. Add(ans,calc(x,y+2));
  91. x++,y++;
  92. }
  93. else {
  94. Add(ans,calc(x,y+1));
  95. if (head>=tail||q[head+1]!=p[i])
  96. break;
  97. head++;
  98. x++;
  99. }
  100. vis[p[i]]=1;
  101. }
  102. cout<<ans<<endl;
  103. }
  104. int main(){
  105. prework();
  106. int T=read();
  107. while (T--)
  108. Main();
  109. return 0;
  110. }

  

UOJ#394. 【NOI2018】冒泡排序的更多相关文章

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

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

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

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

  3. [NOI2018]冒泡排序

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

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

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

  5. BZOJ5416 NOI2018冒泡排序(动态规划+组合数学)

    打表可以发现相当于不存在长度>=3的递减子序列. 考虑枚举在哪一位第一次不卡限制.注意到该位一定会作为前缀最大值.判掉已确定位不合法的情况后,现在的问题即为求长度为i.首位>j的合法排列个 ...

  6. P4769 [NOI2018]冒泡排序(dp)

    传送门 日常膜拜shadowice巨巨的题解 //minamoto #include<bits/stdc++.h> #define R register #define ll long l ...

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

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

  8. NOI2010~NOI2018选做

    [NOI2010] [NOI2010]海拔 高度只需要0/1,所以一个合法方案就是一个割,平面图求最小割. [NOI2010]航空管制 反序拓扑排序,每次取出第一类限制最大的放置,这样做答案不会更劣. ...

  9. Codeforces Round #449 Div. 1

    B:注意到nc/2<=m,于是以c/2为界决定数放在左边还是右边,保证序列满足性质的前提下替换掉一个数使得其更靠近边界即可. #include<iostream> #include& ...

随机推荐

  1. 3194. 【HNOI模拟题】化学(无标号无根树计数)

    Problem 求\(n\)个点的每个点度数不超过\(4\)的无标号无根树个数. Data constraint \(1\le n\le 500\) Solution 尝试着把问题一般化.我们来考虑一 ...

  2. Navicat断开连接解决办法

  3. BSON数据格式

    BSON https://baike.baidu.com/item/BSON 概念 编辑 BSON()是一种类json的一种二进制形式的存储格式,简称Binary JSON,它和JSON一样,支持内嵌 ...

  4. 开源顶级持久层框架——mybatis(ibatis)——day02

    mybatis第二天    高级映射 查询缓存 和spring整合          课程复习:         mybatis是什么?         mybatis是一个持久层框架,mybatis ...

  5. python学习06

    流控制 和函数 1)流控制 1.条件语句 if elif else  if else 2.循环语句 while for 3.continue 和break continue是跳过本次循环,执行下一次循 ...

  6. python学习05

    数据类型之字典dict.set集合 1).字典dict 1. dict_1={'name':'tom','age':18} 是以键值对(key-value)的方式,其中键是可hash值的,即表示键是唯 ...

  7. javascript嵌套java实现jsp

    <%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% ...

  8. [转] 图解Seq2Seq模型、RNN结构、Encoder-Decoder模型 到 Attention

    from : https://caicai.science/2018/10/06/attention%E6%80%BB%E8%A7%88/ 一.Seq2Seq 模型 1. 简介 Sequence-to ...

  9. RNN,写起来真的烦

    曾经,为了处理一些序列相关的数据,我稍微了解了一点递归网络 (RNN) 的东西.由于当时只会 tensorflow,就从官网上找了一些 tensorflow 相关的 demo,中间陆陆续续折腾了两个多 ...

  10. RNN回归

    import torch from torch import nn import numpy as np import matplotlib.pyplot as plt # torch.manual_ ...