博客
关于我
[AGC028-E][树状数组]High Elements
阅读量:120 次
发布时间:2019-02-26

本文共 3589 字,大约阅读时间需要 11 分钟。

翻译

在这里插入图片描述

题解

菜逼选手又来报到啦!

对于字典序最小的问题,我们显然是用按位确定的思想
定义几个变量方便使用
c n t 0 cnt0 cnt0表示 A A A序列当前有多少个前缀最大值, c n t 1 cnt1 cnt1表示 B B B序列当前有多少个前缀最大值
m x 0 mx0 mx0表示 A A A序列当前的最大值, m x 1 mx1 mx1表示 B B B序列当前的最大值
对于第 i i i位的确定工作,先分析能对序列大小做出贡献的序列的性质
假设我们后面能分成两个前缀最大值序列 C C C D D D,满足 s i z ( A ) + s i z ( C ) = s i z ( B ) + s i z ( D ) siz(A)+siz(C)=siz(B)+siz(D) siz(A)+siz(C)=siz(B)+siz(D),且满足 A C AC AC合并与 B D BD BD合并后前缀最大值仍是前缀最大值,显然剩下的数总有方法填入的,故合法
分析序列 C C C D D D的性质
先找出原序列的所有前缀最大值,不妨设这个序列为 E E E
给出结论就是 C , D C,D C,D之中至少有一个序列满足是 E E E的完全子集,证明考虑反证
C , D C,D C,D中均存在至少一个数非原序列前缀最大值,则交换两数后 C , D C,D C,D的前缀最大值个数均减少 1 1 1,因为能制裁他们的都在对面的序列。连续做如上过程,我们总能使得其中至少一个序列成为 E E E的完全子集
不妨枚举哪个序列成为了完全子集,以 C C C为例
如果 D D D序列中存在 E E E x x x个元素,存在非 E E E序列中的 m m m个元素,且第 i i i位之后存在 T T T E E E中的元素,我们可以列出方程
c n t 0 + T − x = c n t 1 + x + m cnt0+T-x=cnt1+x+m cnt0+Tx=cnt1+x+m
移项可知是
c n t 0 − c n t 1 + T = 2 ∗ x + m cnt0-cnt1+T=2*x+m cnt0cnt1+T=2x+m
左边是常数,我们仅需要知道右边能构成这样的序列即可
将是 E E E序列中的元素的权设为 2 2 2,其他的元素权设为 1 1 1,则我们需要知道一个上升序列且其权能够组成 2 ∗ x + m 2*x+m 2x+m
分奇偶讨论,我们发现如果一个数 u u u能够组成,则 u − 2 u-2 u2也能够组成
维护两个 b i t bit bit,支持最大值查询即可

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long#define mp(x,y) make_pair(x,y)#define pll pair
#define pii pair
using namespace std;inline int read(){ int f=1,x=0;char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){ x=x*10+ch-'0';ch=getchar();} return x*f;}int stack[20];inline void write(int x){ if(x<0){ putchar('-');x=-x;} if(!x){ putchar('0');return;} int top=0; while(x)stack[++top]=x%10,x/=10; while(top)putchar(stack[top--]+'0');}inline void pr1(int x){ write(x);putchar(' ');}inline void pr2(int x){ write(x);putchar('\n');}const int MAXN=200005;int n;int lowbit(int x){ return x&-x;}struct bittree{ int s[MAXN]; void modify(int x,int c){ for(;x<=n;x+=lowbit(x))s[x]=max(s[x],c);} int qry(int x){ int ret=0;for(;x>=1;x-=lowbit(x))ret=max(ret,s[x]);return ret;}}bi[2];int L[MAXN],R[MAXN],a[MAXN];int is[MAXN],sum;int re[2][MAXN][20];void rebuild(int i){ int u=n-a[i]+1; for(int x=u,cnt=1;x<=n;x+=lowbit(x),cnt++)bi[0].s[x]=re[0][i][cnt]; for(int x=u,cnt=1;x<=n;x+=lowbit(x),cnt++)bi[1].s[x]=re[1][i][cnt];}void getit(int i){ int u=n-a[i]+1; for(int x=u,cnt=1;x<=n;x+=lowbit(x),cnt++)re[0][i][cnt]=bi[0].s[x]; for(int x=u,cnt=1;x<=n;x+=lowbit(x),cnt++)re[1][i][cnt]=bi[1].s[x];}void init(){ int mx=0; for(int i=1;i<=n;i++)if(a[i]>mx)is[i]=1,mx=a[i],sum++; for(int i=n;i>=1;i--) { int u=n-a[i]+1; int u1=bi[0].qry(u-1),u2=bi[1].qry(u-1); if(is[i])u1+=2,u2+=2; else u1+=1,u2+=1; getit(i); bi[u1&1].modify(u,u1);bi[u2&1].modify(u,u2); }}int ans[MAXN];int mx[2],cnt[2];bool ok(int i,int o){ cnt[o]+=(a[i]>mx[o]); int u=n-mx[o^1]+1,c1=bi[0].qry(u-1),c2=bi[1].qry(u-1); int cal=cnt[o]-cnt[o^1]+sum; cnt[o]-=(a[i]>mx[o]); if(cal>=0) { if((cal&1)&&cal<=c2)return true; if((!(cal&1))&&cal<=c1)return true; } int ls=mx[o]; cnt[o]+=(a[i]>mx[o]);mx[o]=max(mx[o],a[i]); u=n-mx[o]+1,c1=bi[0].qry(u-1),c2=bi[1].qry(u-1); cal=cnt[o^1]-cnt[o]+sum; mx[o]=ls;cnt[o]-=(a[i]>mx[o]); if(cal>=0) { if((cal&1)&&cal<=c2)return true; if((!(cal&1))&&cal<=c1)return true; } return false;}int main(){ n=read(); for(int i=1;i<=n;i++)a[i]=read(); init(); for(int i=1;i<=n;i++) { rebuild(i);sum-=is[i]; if(ok(i,0))ans[i]=0,cnt[0]+=(a[i]>mx[0]),mx[0]=max(mx[0],a[i]); else if(ok(i,1))ans[i]=1,cnt[1]+=(a[i]>mx[1]),mx[1]=max(mx[1],a[i]); else return puts("-1"),0; } for(int i=1;i<=n;i++)putchar(ans[i]+'0'); puts(""); return 0;}

转载地址:http://remu.baihongyu.com/

你可能感兴趣的文章
Mysql中怎样使用update更新某列的数据减去指定值
查看>>
Mysql中怎样设置指定ip远程访问连接
查看>>
mysql中数据表的基本操作很难嘛,由这个实验来带你从头走一遍
查看>>
Mysql中文乱码问题完美解决方案
查看>>
mysql中的 +号 和 CONCAT(str1,str2,...)
查看>>
Mysql中的 IFNULL 函数的详解
查看>>
mysql中的collate关键字是什么意思?
查看>>
MySql中的concat()相关函数
查看>>
mysql中的concat函数,concat_ws函数,concat_group函数之间的区别
查看>>
MySQL中的count函数
查看>>
MySQL中的DB、DBMS、SQL
查看>>
MySQL中的DECIMAL类型:MYSQL_TYPE_DECIMAL与MYSQL_TYPE_NEWDECIMAL详解
查看>>
MySQL中的GROUP_CONCAT()函数详解与实战应用
查看>>
MySQL中的IO问题分析与优化
查看>>
MySQL中的ON DUPLICATE KEY UPDATE详解与应用
查看>>
mysql中的rbs,SharePoint RBS:即使启用了RBS,内容数据库也在不断增长
查看>>
mysql中的undo log、redo log 、binlog大致概要
查看>>
Mysql中的using
查看>>
MySQL中的关键字深入比较:UNION vs UNION ALL
查看>>
mysql中的四大运算符种类汇总20多项,用了三天三夜来整理的,还不赶快收藏
查看>>