BZOJ 1858

1858: [Scoi2010]序列操作

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 2489  Solved: 1228
[Submit][Status][Discuss]

Description

lxhgww最近收到了一个01序列,序列里面包含了n个数,这些数要么是0,要么是1,现在对于这个序列有五种变换操作和询问操作:
0 a b 把[a, b]区间内的所有数全变成0
1 a b 把[a, b]区间内的所有数全变成1
2 a b 把[a,b]区间内的所有数全部取反,也就是说把所有的0变成1,把所有的1变成0
3 a b 询问[a, b]区间内总共有多少个1
4 a b 询问[a, b]区间内最多有多少个连续的1
对于每一种询问操作,lxhgww都需要给出回答,聪明的程序员们,你们能帮助他吗?

Input

输入数据第一行包括2个数,n和m,分别表示序列的长度和操作数目 第二行包括n个数,表示序列的初始状态 接下来m行,每行3个数,op, a, b,(0<=op<=4,0<=a<=b<n)表示对于区间[a, b]执行标号为op的操作="" <="" div="">

Output

对于每一个询问操作,输出一行,包括1个数,表示其对应的答案

Sample Input

10 10
0 0 0 1 1 0 1 0 1 1
1 0 2
3 0 5
2 2 2
4 0 4
0 3 6
2 3 7
4 2 8
1 0 5
0 5 6
3 3 9

Sample Output

5
2
6
5

HINT

对于30%的数据,1<=n, m<=1000
对于100%的数据,1<=n, m<=100000

Source

Day2

 

Solution

直接用线段树维护

Code

  1 #include<stdio.h>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 #define N 100005
  7 using namespace std;
  8 int n,m;
  9 struct seg
 10 {
 11     int l1,l0,r1,r0,m1,m0,s1,s0;
 12     int l,r;
 13     int rev,c,full;
 14 }t[N<<2];
 15 void rev(int k)
 16 {
 17     swap(t[k].l1,t[k].l0);
 18     swap(t[k].r1,t[k].r0);
 19     swap(t[k].m1,t[k].m0);
 20     swap(t[k].s1,t[k].s0);
 21     if(t[k].full!=-1)t[k].full^=1;
 22 }
 23 void color(int k,int v)
 24 {
 25     t[k].rev=0;
 26     int s=t[k].r-t[k].l+1;
 27     if(v)
 28     {
 29         t[k].s0=t[k].m0=t[k].l0=t[k].r0=0;
 30         t[k].s1=t[k].m1=t[k].l1=t[k].r1=s;
 31     }else
 32     {
 33         t[k].s0=t[k].m0=t[k].l0=t[k].r0=s;
 34         t[k].s1=t[k].m1=t[k].l1=t[k].r1=0;
 35     }
 36     t[k].full=v;
 37 }
 38 /*
 39 seg merge(seg a,seg b)
 40 {
 41     seg tmp;tmp.l=a.l;tmp.r=b.r;
 42     tmp.rev=0;tmp.c=-1;
 43     tmp.l0=a.l0;tmp.l1=a.l1;
 44     tmp.r0=b.r0;tmp.r1=b.r1;
 45     tmp.m0=max(max(a.m0,b.m0),a.r0+b.l0);
 46     tmp.m1=max(max(a.m1,b.m1),a.r1+b.l1);
 47     tmp.s0=a.s0+b.s0;
 48     tmp.s1=a.s1+b.s1;
 49     if(a.full==0)tmp.l0=a.m0+b.l0;
 50     else if(a.full==1)tmp.l1=a.m1+b.l1;
 51     if(b.full==0)tmp.r0=a.r0+b.m0;
 52     else if(b.full==1)tmp.r1=a.r1+b.m1;
 53     if(a.full=b.full)tmp.full=a.full;
 54     else tmp.full=-1;
 55     return tmp;
 56 }*/
 57 seg merge(seg a,seg b) 
 58 {
 59     seg tmp;tmp.l=a.l;tmp.r=b.r;
 60     tmp.rev=0;tmp.c=-1;
 61     tmp.l0=a.l0;tmp.l1=a.l1;
 62     tmp.r0=b.r0;tmp.r1=b.r1;
 63     tmp.m0=max(max(a.m0,b.m0),a.r0+b.l0);
 64     tmp.m1=max(max(a.m1,b.m1),a.r1+b.l1);
 65     tmp.s0=a.s0+b.s0;
 66     tmp.s1=a.s1+b.s1;
 67     if(a.full==0)tmp.l0=a.m0+b.l0;
 68     else if(a.full==1)tmp.l1=a.m1+b.l1;
 69     if(b.full==0)tmp.r0=b.m0+a.r0;
 70     else if(b.full==1)tmp.r1=b.m1+a.r1;
 71     if(a.full==b.full)tmp.full=a.full;
 72     else tmp.full=-1;
 73     return tmp;
 74 }
 75 void pushup(int k)
 76 {t[k]=merge(t[k<<1],t[k<<1|1]);}
 77 void pushdown(int k)
 78 {
 79     if(t[k].l==t[k].r)return;
 80     if(t[k].c!=-1)
 81     {
 82         t[k<<1].c=t[k<<1|1].c=t[k].c;
 83         color(k<<1,t[k].c);color(k<<1|1,t[k].c);
 84         t[k].c=-1;
 85     }
 86     if(t[k].rev)
 87     {
 88         t[k<<1].rev^=1;
 89         t[k<<1|1].rev^=1;
 90         rev(k<<1);rev(k<<1|1);
 91         t[k].rev=0;
 92     }        
 93 }
 94 void build(int k,int l,int r)
 95 {
 96     t[k].l=l;t[k].r=r;
 97     t[k].c=-1;
 98     if(l==r)
 99     {
100         scanf("%d",&t[k].full);
101         if(t[k].full)
102         {t[k].l1=t[k].r1=t[k].m1=t[k].s1=1;}
103         else
104         {t[k].l0=t[k].r0=t[k].m0=t[k].s0=1;}
105         return;
106     }
107     int mid=(l+r)>>1;
108     build(k<<1,l,mid);build(k<<1|1,mid+1,r);
109     pushup(k);
110 }
111 void change(int k,int x,int y,int v)
112 {
113     pushdown(k);
114     int l=t[k].l,r=t[k].r;
115     if(l==x && r==y)
116     {
117         color(k,v);
118         t[k].c=v;
119         return;
120     }
121     int mid=(l+r)>>1;
122     if(mid>=y)change(k<<1,x,y,v);
123     else if(mid<x)change(k<<1|1,x,y,v);
124     else
125     {
126         change(k<<1,x,mid,v);
127         change(k<<1|1,mid+1,y,v);
128     }
129     pushup(k);
130 }
131 void reverse(int k,int x,int y)
132 {
133     pushdown(k);
134     int l=t[k].l,r=t[k].r;
135     if(l==x && r==y)
136     {
137         rev(k);
138         t[k].rev=1;
139         return;
140     }
141     int mid=(l+r)>>1;
142     if(mid>=y)reverse(k<<1,x,y);
143     else if(mid<x)reverse(k<<1|1,x,y);
144     else
145     {
146         reverse(k<<1,x,mid);
147         reverse(k<<1|1,mid+1,y);
148     }
149     pushup(k);
150 }
151 seg ask(int k,int x,int y)
152 {
153     pushdown(k);
154     int l=t[k].l,r=t[k].r;
155     if(l==x && r==y)return t[k];
156     int mid=(l+r)>>1;
157     if(mid>=y)return ask(k<<1,x,y);
158     else if(mid<x)return ask(k<<1|1,x,y);
159     else return merge(ask(k<<1,x,mid),ask(k<<1|1,mid+1,y));
160 }
161 int asksum(int k,int x,int y)
162 {
163     pushdown(k);
164     int l=t[k].l,r=t[k].r;
165     if(l==x && r==y)return t[k].s1;
166     int mid=(l+r)>>1;
167     if(mid>=y)return asksum(k<<1,x,y);
168     else if(mid<x)return asksum(k<<1|1,x,y);
169     else return asksum(k<<1,x,mid)+asksum(k<<1|1,mid+1,y);
170 }
171 int main()
172 {
173     scanf("%d%d",&n,&m);
174     build(1,1,n);
175     for(int i=0;i<m;i++)
176     {
177         int f,x,y;
178         scanf("%d%d%d",&f,&x,&y);
179         x++;y++;
180         if(f==0)change(1,x,y,0);
181         if(f==1)change(1,x,y,1);
182         if(f==2)reverse(1,x,y);
183         if(f==3)printf("%d\n",asksum(1,x,y));
184         if(f==4)printf("%d\n",ask(1,x,y).m1);
185     }
186 //    system("pause");
187     return 0;
188 }

 

posted @ 2017-02-19 11:20  hyf20010101  阅读(231)  评论(0编辑  收藏  举报