枚举$a_{i}$并判断是否可行,有以下结论:若$a_{i}$可以留下来,一定存在一种合法方案使得$a_{i}$仅参与最后若干次合并,且第一次参与合并前左右都不超过2个数
证明:将大于$a_{i}$的看成1,小于$a_{i}$的看成0,将合并分为两类:
1.都在左/右区间,那么相当于删除了最右/左边的$01/10$,若存在3个数,可以将倒数第3个数与$01/10$合并去删除
2.左右区间各有1个,当达到3个后,不管是$000$和$111$还是$010$和$101$都可以预先合并再与$a_{i}$合并
根据上述结论,我们可以对两边分别求出最终结果能否为$0,00,1,11,01/10$,并判断能否组合即可
(可以保留$a_{i}$的组合方法有8种:$0-1$,$1-0$,$00-11$,$11-00$,$01/10-01/10$)
 对这些结果分为两类进行判断:
1.全部相同(即$0/00/1/11$):以0为例,不断插入一个数字,要合并当且仅当以$111$或$10$为结尾(特别的,如果$10$是最后两个数,那么就无解,也可以删除掉),证明略(贪心策略中$10$消除是为了更好地消除$111$)
具体维护方法:根据贪心,可以发现插入并合并完后一定是若干个$0$和不超过2个$1$,对0和1的个数进行维护,最后只需要判断0的个数是否比1的多即可
2.$01/10$,首先长度必须要为偶数,之后考虑如果$0$和$1$个数相同,那么一定存在相邻的$01/10$且必然有别的数(否则就已经完成了),不断消除$01/10$即可
假设$1$的个数比$0$的个数多,按照第一种方案的贪心,有解必然存在一次合并后满足$0$的个数和$1$的个数一样多(包括未插入的部分),即最终状态下$0$的个数不小于比$1$的个数,证明略
但这样的复杂度为$o(n^{2})$,需要优化:
从小到大枚举$a_{i}$,那么每一次相当于将一个位置上的$1$变成$0$,考虑要维护哪些信息:1.两种贪心时的最终状态;2.$0$的个数和$1$的个数

 1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 1000005
4 #define L (k<<1)
5 #define R (L+1)
6 #define mid (l+r>>1)
7 struct sta{
8 int x,y;
9 };
10 struct ji{
11 int k;
12 sta a[2];
13 }o,o0,o1;
14 struct type{
15 ji p0,p1;
16 }f[N<<2];
17 int t,n,a[N],id[N],ans[N];
18 sta merge(sta x,sta y){
19 sta z;
20 z.x=x.x+max(y.x-x.y,0);
21 z.y=(y.y+max(x.y-y.x,0)-1)%2+1;
22 return z;
23 }
24 type merge(type x,type y){
25 type z;
26 z.p0.k=x.p0.k+y.p0.k;
27 z.p1.k=x.p1.k+y.p1.k;
28 z.p0.a[0]=merge(x.p0.a[0],y.p0.a[0]);
29 z.p0.a[1]=merge(y.p0.a[1],x.p0.a[1]);
30 z.p1.a[0]=merge(x.p1.a[0],y.p1.a[0]);
31 z.p1.a[1]=merge(y.p1.a[1],x.p1.a[1]);
32 return z;
33 }
34
35 void build(int k,int l,int r){
36 if (l==r){
37 f[k]=type{o0,o1};
38 return;
39 }
40 build(L,l,mid);
41 build(R,mid+1,r);
42 f[k]=merge(f[L],f[R]);
43 }
44 void update(int k,int l,int r,int x){
45 if (l==r){
46 f[k]=type{o1,o0};
47 return;
48 }
49 if (x<=mid)update(L,l,mid,x);
50 else update(R,mid+1,r,x);
51 f[k]=merge(f[L],f[R]);
52 }
53 type query(int k,int l,int r,int x,int y){
54 if ((l>y)||(x>r))return type{o,o};
55 if ((x<=l)&&(r<=y))return f[k];
56 return merge(query(L,l,mid,x,y),query(R,mid+1,r,x,y));
57 }
58 bool pd(type k,int p,int x){
59 if (!x)return k.p0.a[p].x>k.p0.a[p].y;
60 if (x==1)return k.p1.a[p].x>k.p1.a[p].y;
61 if (x==2){
62 if (k.p0.k==k.p1.k)return 1;
63 if (k.p0.k<k.p1.k)return k.p0.a[p].x>=k.p0.a[p].y;
64 return k.p1.a[p].x>=k.p1.a[p].y;
65 }
66 }
67 int main(){
68 o0.a[0].y=o0.a[1].y=1;
69 o1.k=o1.a[0].x=o1.a[1].x=1;
70 scanf("%d",&t);
71 while (t--){
72 scanf("%d",&n);
73 for(int i=1;i<=n;i++){
74 scanf("%d",&a[i]);
75 ans[i]=0;
76 id[a[i]]=i;
77 }
78 build(1,1,n);
79 for(int i=1;i<=n;i++){
80 update(1,1,n,id[i]);
81 type x=query(1,1,n,1,id[i]-1),y=query(1,1,n,id[i]+1,n);
82 if ((pd(x,0,0))&&(pd(y,1,1))||(pd(x,0,1))&&(pd(y,1,0))||(pd(x,0,2))&&(pd(y,1,2)))ans[id[i]]=1;
83 }
84 for(int i=1;i<=n;i++)printf("%d",ans[i]);
85 printf("\n");
86 }
87 }

[nowcoder5669E]Eliminate++的更多相关文章

  1. Effective Java 06 Eliminate obsolete object references

    NOTE Nulling out object references should be the exception rather than the norm. Another common sour ...

  2. Effective Java 24 Eliminate unchecked warnings

    Note Eliminate every unchecked warning that you can. Set<Lark> exaltation = new HashSet(); The ...

  3. hdu 4115 Eliminate the Conflict ( 2-sat )

    Eliminate the Conflict Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  4. HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011亚洲北京赛区网络赛)

    HDU 4041 Eliminate Witches! (模拟题 ACM ICPC 2011 亚洲北京赛区网络赛题目) Eliminate Witches! Time Limit: 2000/1000 ...

  5. hdu4115 Eliminate the Conflict

    Eliminate the Conflict Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Othe ...

  6. Once you eliminate all the other factors,the only thing remaining must be the truth.

    Once you eliminate all the other factors,the only thing remaining must be the truth. 一旦你排除了杂因,剩下的一定是 ...

  7. HDU 4115 Eliminate the Conflict(2-SAT)(2011 Asia ChengDu Regional Contest)

    Problem Description Conflicts are everywhere in the world, from the young to the elderly, from famil ...

  8. 把配置和环境解耦 eliminate “works on my machine” problems when collaborating on code with co-workers docker架构与解决的问题

    Docker实践 - 懒人的技术笔记 - 博客频道 - CSDN.NET  http://blog.csdn.net/lincyang/article/details/43055061 Docker直 ...

  9. HDU 4115 Eliminate the Conflict(2-sat)

    HDU 4115 Eliminate the Conflict pid=4115">题目链接 题意:Alice和Bob这对狗男女在玩剪刀石头布.已知Bob每轮要出什么,然后Bob给Al ...

随机推荐

  1. 【Ubuntu】VirtualBox 您没有查看“sf_VirtualDisk”的内容所需的权限

    ​ 但是现在发现无法去访问,没有权限: ​ 即使是: crifan@crifan-Ubuntu:~$ sudo chown -R crifan /media/sf_win7_to_ubuntu/ cr ...

  2. C语言对"不定长"字符串数组的遍历

    一般来说,c语言的数组的初始化可以通过三种方式: {0},在声明时使用,如 int a[10]={0} 使用memset, memset(array,0,sizeof(array)) 用for循环赋值 ...

  3. C语言中while 语句

    while的执行顺序 while 循环的执行顺序非常简单,它的格式是: while (表达式) { 语句: } 概念:当表达式为真,则执行下面的语句:语句执行完之后再判断表达式是否为真,如果为真,再次 ...

  4. pycharm中的terminal和Windows命令提示符有什么区别?二者用pip安装的包是不是位于相同位置?

    那要看pycharm使用了什么shell,可以在设置->工具->终端里查看shell path.如果使用的是cmd.exe那就没区别.pycharm终端和Windows命令提示符用pip安 ...

  5. Java编程开发学习路线图(附所有免费课程+在线自测)

    转自  https://yq.aliyun.com/articles/134286?spm=5176.100239.0.0.1UfveS 摘要: 长期以来,Java一直占据TIOBE编程语言排行版第一 ...

  6. 第二次Alpha Scrum Meeting

    本次会议为Alpha阶段第二次Scrum Meeting会议 会议概要 会议时间:2021年4月24日 会议地点:线上会议 会议时长:30min 会议内容简介:本次会议主要由每个人展示自己目前完成的工 ...

  7. str数组

  8. Python课程笔记(三)

    1.python定义类.创建对象 class Myclass: # 定义Myclass类 def sum(self,x,y): self.x = x self.y = y return self.x+ ...

  9. 『学了就忘』Linux基础 — 5、使用VMware创建虚拟机

    目录 1.在VMware中创建虚拟机 (1)点击[创建新的虚拟机]. (2)选择系统安装方式 (3)选择客户机操作系统 (4)自定义虚拟机的名称和安装位置. (5)指定系统硬盘容量 (6)完成创建 2 ...

  10. 字符串与模式匹配算法(四):BM算法

    一.BM算法介绍 BM算法(Boyer-Moore算法)是罗伯特·波义尔(Robert Boyer)和杰·摩尔(J·Moore)在1977年共同提出的.与KMP算法不同的是,BM算法是模式串P由左向右 ...