LINK:冒泡排序

神题。

可以想到爆搜 期望得分5~10分。

打成这个样子心态不得爆炸?

仔细分析 一个不合法序列还有什么标志.

容易想到某个数字离自己位置相反的方向多走了一步.

考虑单独对每个数字进行分析 每次都是这个数字前面的数字会让它多走一步.

对于每个位置 i 位置上的数字 \(a_i\) \(cnt_i\)表示前面有多少个数字比其大。

那么有 \(i-cnt_i<a_i\)那么就不合法了。

考虑状压 对于字典序可以利用总方案-<=的方案来做 类似数位dp。

期望得分44.

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 10000000000000000ll
#define inf 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-10
#define sq sqrt
#define S second
#define F first
#define mod 998244353
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f; }
const int MAXN=18,maxn=600010;
int n,T;
int a[maxn];
int f[1<<MAXN],c[1<<MAXN];
int g[1<<MAXN][2];
int maxx;
inline void add(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
int main()
{
//freopen("1.in","r",stdin);
get(T);
int ww=1<<18;
vep(1,ww,i)c[i]=c[i>>1]+(i&1);
while(T--)
{
get(n);
rep(1,n,i)get(a[i]);
if(n<=18)
{
rep(0,maxx,i)f[i]=g[i][0]=g[i][1]=0;
maxx=1<<n;--maxx;
f[0]=1;g[0][1]=1;
rep(0,maxx-1,i)
{
if(!f[i])continue;
int cnt=0;
fep(n,1,j)
{
if(i&(1<<(j-1))){++cnt;continue;}
int s=i|(1<<(j-1));
if(cnt&&c[s]-cnt<j)continue;
add(f[s],f[i]);
add(g[s][0],g[i][0]);
if(j>a[c[s]])continue;
if(j==a[c[s]])add(g[s][1],g[i][1]);
else add(g[s][0],g[i][1]);
}
}
//put(g[1][1]);
put((f[maxx]-g[maxx][0]-g[maxx][1]+mod)%mod);
}
}
return 0;
}

我以为想到这个地方就在第5层了 可是正解大概在第37层.

进一步规约发现的性质。

会出现不合法的情况 一个是前面比其数字多的数字已经让他跑到超过自己位置了。

考虑恰好到其位置的时候 前面还有比其大的数字那么后面一定还存在一个比其小的数字。

那么 由于后面的数字一直存在 那么一开始就是那个局面 一堆比x大的在x前面 后面还有一个比x要小的。

此时可以想到x也会跑到后面去更新比它小的数字 那么前面的数字在让x一直往前的之后 x的位置一定是<x的。

不然x是不会跑到后面更新那个比它小的数字而且更新完后自己还没有办法回到原位.

但是这个条件是前面至少有一个比x大 然后越过x的位置 可以看成后面存在一个<x的数字。

这样 规律就被直接推出来了 即不存在长度为3的下降子序列。

推出来就不需要证明了。

尽管过程略显生硬 但是非常符合逻辑

接下来需要dp了。

先不管字典序。

那么dp出所有合法的序列也是一件困难的事情。

还是由\(i\)推\(i+1\) 考虑第一位放什么。

假设放x 那么比x大的还是可以随便放第二位的 但是比x要小的话需要1~x-1要整齐出现.

此时容易想到 设\(f_{i,j}\)表示长度为i 以j开头的方案数.

那么有 \(f_{i,j}=\sum_{l=max(1,j-1)}^{i-1}f_{i-1,l}\)

这样就可以\(n^2\)递推了.

考虑如何求答案.

欲知后事如何 且听下回分解

update 7.26 继续营业:

没有限制答案就是\(\sum_{i=1}^nf_{n,i}\)

由于答案要求严格比某个排列字典序要大.

我们之所以求这个数组就是为了比较方便的得到答案.

和答案一一比较字典序.到了第i个位置我们要求的是前i-1个位置上的数字相同.

那么当前位置要填x 显然\(x>a_i\) 为了满足要求x还要大于前缀最大值.

为了证明后者 先分类讨论一波 如果前缀最大值\(>a_i\) 那么\(x<\)前缀最大值.

此时放x 后面肯定存在一个\(a_i\)一定是不合法的.

如果前缀最大值等于\(a_i\)显然x要大于\(a_i\) 所以x还是要大于前缀最大值.

我们就可以得到哪些能用数字的集合 \(mx_i+1~n\) 其中\(mx_i\)为\(max_{j=1}^ia_i\)

同时 此时能用的数字个数为n-i+1 这些数字排名也就有了 累加f数值即可.即:

\(\sum_{j=n-i+1-n+mx_i+1}^{n-i+1}f_{n-i+1,j}\)

这样就有一个\(n^2\)的做法了.

期望得分80

code
//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<ctime>
#include<cctype>
#include<queue>
#include<deque>
#include<stack>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define inf 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007ll
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-10
#define sq sqrt
#define S second
#define F first
#define mod 998244353
#define len(x) t[x].len
#define f(x) t[x].fa
using namespace std;
char *fs,*ft,buf[1<<15];
inline char gc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=gc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=gc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=gc();}
return x*f; }
const int MAXN=1010;
int n,T;
int f[MAXN][MAXN];
int a[MAXN],mn[MAXN];
inline void add(int &x,int y){x=x+y>=mod?x+y-mod:x+y;}
inline int mus(int x,int y){return x-y<0?x-y+mod:x-y;}
int main()
{
//freopen("1.in","r",stdin);
get(T);n=1000;
f[1][1]=1;
rep(2,n,i)
{
int sum=0;
rep(1,i-1,j)add(sum,f[i-1][j]);
f[i][1]=f[i][2]=sum;
rep(3,i,j)
{
sum=mus(sum,f[i-1][j-2]);
f[i][j]=sum;
}
}
while(T--)
{
get(n);int ans=0;
rep(1,n,i)get(a[i]);
mn[n]=a[n];fep(n-1,1,i)mn[i]=min(a[i],mn[i+1]);
int mx=0,cmx=0;
rep(1,n,i)
{
if(cmx>mn[i])break;
if(mx>a[i])cmx=max(cmx,a[i]);
mx=max(mx,a[i]);
rep(n-i+1-n+mx+1,n-i+1,j)add(ans,f[n-i+1][j]);
}
put(ans);
}
return 0;
}

不管是f数组还是f数组的后缀和 这都是\(n^2\)的.

考虑优化.

欲知后事如何 请听下回分解

luogu P4769 [NOI2018]冒泡排序 结论 树状数组 卡特兰数的更多相关文章

  1. [luogu]P2657低头一族[树状数组]

    [luogu]P2657 低头一族 题目描述 一群青年人排成一队,用手机互相聊天. 每个人的手机有一个信号接收指标,第i个人的接收指标设为v[i]. 如果位置在x[i]的人要和位置在xj的人聊天,那么 ...

  2. Luogu P3374 【模板】树状数组 1

    真正的模板题. 树状数组的思想很简单(不如说背代码更简单),每个节点记录多个节点的信息(每个点存x&(-x)个). 道理可以参见很多大佬的博客,最后前缀和的思想搞一下就好了.不想说也不会说. ...

  3. Luogu P4901 排队 fib数列+树状数组+倍增

    这题让我升华..还好只重构了一遍 首先我们发现:$n$较小时,整个队伍的形态 跟 $n$ 比较大时的局部是一样的 所以我们预处理出这个队伍的形态,和每一行每个位置的质因子个数的前缀和,$O(nlogn ...

  4. 【Luogu】P2617Dynamic Ranking(树状数组套主席树)

    题目链接 树状数组套主席树有点难懂qwq 不好理解 树状数组套主席树的直观理解应该是:树状数组的每一个节点是一棵主席树. 普通区间修改我们是创建1个线段树,树状数组套主席树的时候我们就创建log个线段 ...

  5. 题解报告:Luogu P3368 【模板】树状数组 2(区间修改,单点查询)

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  6. 4.9 省选模拟赛 划分序列 二分 结论 树状数组优化dp

    显然发现可以二分. 对于n<=100暴力dp f[i][j]表示前i个数分成j段对于当前的答案是否可行. 可以发现这个dp是可以被优化的 sum[i]-sum[j]<=mid sum[i] ...

  7. 树状数组例题-数星星,简单题easy,校门外的树2,清点人数

    [例1]数星星 天空中有一些星星,这些星星都在不同的位置,每个星星都有个坐标,如果一个星星的左下方(包括正左和正下)有k颗星星,就说这颗星星是k级的. 比如,上图中,星星5是3级的(1,2,4在其左下 ...

  8. luogu P3368 【模板】树状数组 2

    题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数数加上x 2.求出某一个数的和 输入输出格式 输入格式: 第一行包含两个整数N.M,分别表示该数列数字的个数和操作的总个数. ...

  9. luogu P2345 奶牛集会 |排序+树状数组

    题目描述 约翰的N 头奶牛每年都会参加"哞哞大会".哞哞大会是奶牛界的盛事.集会上的活动很多,比如堆干草,跨栅栏,摸牛仔的屁股等等.它们参加活动时会聚在一起,第i 头奶牛的坐标为X ...

随机推荐

  1. 升降梯上——玄学dp

    升降梯上 题目描述 开启了升降梯的动力之后,探险队员们进入了升降梯运行的那条竖直的隧道,映入眼帘的是一条直通塔顶的轨道.一辆停在轨道底部的电梯.和电梯内一杆控制电梯升降的巨大手柄. \(Nescafe ...

  2. [JAVA]解决不同浏览器下载附件的中文名乱码问题

    附件下载时,遇到中文附件名的兼容性问题,firefox.chrome.ie三个派系不兼容,通过分析整理,总结出处理该问题的办法,记录如下: 1.文件名编码 服务器默认使用的是ISO8859-1,而我们 ...

  3. uni-app 使用个推推送系统消息

    原文可查看此处 ,搜索 uni-app 使用个推推送系统消息 https://mp.weixin.qq.com/mp/profile_ext?action=home&__biz=Mzg3NTA ...

  4. day13 作业

    目录 1.编写文件修改功能,调用函数时,传入三个参数(修改的文件路径,要修改的内容,修改后的内容)既可完成文件的修改 2.编写tail工具 3.编写登录功能 4.编写注册功能 选做题:编写ATM程序实 ...

  5. python 爬虫由于网络或代理不能用导致的问题处理方法

    平时在爬取某些网页的时候,可能是由于网络不好或者代理池中的代理不能用导致请求失败.此时有们需要重复多次去请求,python中有现成的,相应的包供我们使用: 我们可以利用retry模块进行多次请求,如果 ...

  6. CSS之Bootstrap(快速布局)

    简介 什么是Bootstrap? Bootstrap官网 框架:库 lib library jQuery作为一个框架来讲,提供一套比较便捷的操作DOM的方式 把大家都需要的功能预先写好到一些文件 这就 ...

  7. Django框架11 /form组件、modelForm组件

    Django框架11 /form组件.modelForm组件 目录 Django框架11 /form组件.modelForm组件 1. form组件介绍 2. form常用字段与插件 3. form所 ...

  8. python小游戏-水文

    脚本不会,全都白费.所以就去学习了简单的python,结果不慎学了python中的pygame,浪费了不少时间,没啥用如果不做游戏个人觉得最好别学,学爬虫她不香吗?不过也有一点收获,打飞机小游戏,源码 ...

  9. Java File类基础解析 1

    Java File类基础解析 1 File类的构造方法 public File(String pathname) :通过给定的路径名字符转换为抽象路径名来创建新的File实例 String path ...

  10. OSCP Learning Notes - Buffer Overflows(1)

    Introduction to Buffer Overflows Anatomy of Memory Anatomy of the Stack Fuzzing Tools: Vulnserver -  ...