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. web标签语义化的理解_web语义化是什么意思

    web语义化是什么? Web语义化,使用语义恰当的标签,可以让页面具有良好的结构,页面元素具有良好的含义,从而让人和机器都能快速理解.语义化的web页面一方面可以让机器在更少的人类干预情况下收集并研究 ...

  2. Java实现 第十一届蓝桥杯——走方格(渴望有题目的大佬能给小编提供一下题目,讨论群:99979568)

    走方格 问题描述在平面上有一些二维的点阵. 这些点的编号就像二维数组的编号一样,从上到下依次为第 1 至第 n 行,从左到右依次为第1 至第 m 列,每一个点可以用行号和列号来表示. 现在有个人站在第 ...

  3. angular入门--列表排序

    首先,先上代码 <html ng-app="app1"> <head> <meta charset='utf-8' /> <meta na ...

  4. 洛谷 P6082 [JSOI2015]salesman

    题意 给定一棵\(n\)个点的树,有点权,你从\(1\)号点开始一次旅行,最后回到\(1\)号点.每到达一个点,你就能获得等于该点点权的收益, 但每个点都有进入该点的次数限制,且每个点的收益只能获得一 ...

  5. 状压DP之集合选数

    题目 [HNOI2012]集合选数 <集合论与图论>这门课程有一道作业题,要求同学们求出{1, 2, 3, 4, 5}的所有满足以 下条件的子集:若 x 在该子集中,则 2x 和 3x 不 ...

  6. Fetch.AI的最新发布speaks your language

    更新增强长期网络的稳定性 包括新的Etch功能,使我们的代码比以往对开发人员更加友好.我们现在支持太阳下的每一种语言,包括普通话,希腊语和希伯来语-甚至表情符号 介绍我们很高兴地宣布我们最新的技术更新 ...

  7. SaaS 系统架构,Spring Boot 动态数据源实现!

    这段时候在准备从零开始做一套SaaS系统,之前的经验都是开发单数据库系统并没有接触过SaaS系统,所以接到这个任务的时候也有也些头疼,不过办法部比困难多,难得的机会. 在网上找了很多关于SaaS的资料 ...

  8. day13 作业

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

  9. gulp-less打包后calc属性计算不准确的问题

    .step-item{ width: calc((100% - 50px) / 2); &:nth-child(2){ margin-right: 0; } } 这样直接写的话,编译时会直接给 ...

  10. DVWA学习记录 PartⅠ

    DVWA介绍 DVWA(Damn Vulnerable Web Application)是一个用来进行安全脆弱性鉴定的PHP/MySQL Web应用,旨在为安全专业人员测试自己的专业技能和工具提供合法 ...