BZOJ1858: [Scoi2010]序列操作

1858: [Scoi2010]序列操作

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 1068  Solved: 545
[Submit][Status]

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

这题的区间合并实在太恶心了,写完我都快吐了。。。那天过来再调吧。。。

代码:

  1 {$inline on}
  2 {$M 1000000000,0,maxlongint}
  3 const maxn=100000+1000;
  4 var s,sum1,sum0,v,lx0,rx0,lx1,rx1,mx0,mx1,fa,id,a:array[0..maxn] of longint;
  5     rev,tag:array[0..maxn] of boolean;
  6     c:array[0..maxn,0..1] of longint;
  7     i,n,m,x,y,z,rt,ch,ll,rr:longint;
  8     procedure swap(var x,y:longint);inline;
  9      var t:longint;
 10      begin
 11       t:=x;x:=y;y:=t;
 12      end;
 13     function max(x,y:longint):longint;inline;
 14      begin
 15       if x>y then exit(x) else exit(y);
 16      end;
 17 procedure pushup(x:longint);
 18  var l,r:longint;
 19  begin
 20    l:=c[x,0];r:=c[x,1];
 21    s[x]:=s[l]+s[r]+1;
 22    sum1[x]:=sum1[l]+sum1[r]+ord(v[x]=1);
 23    sum0[x]:=sum0[l]+sum0[r]+ord(v[x]=0);
 24    if lx0[l]=s[l] then
 25      begin
 26      if v[x]=0 then lx0[x]:=s[l]+1+lx0[r]
 27      else lx0[x]:=s[l];
 28      end
 29    else lx0[x]:=lx0[l];
 30    if rx0[r]=s[r] then
 31      begin
 32      if v[x]=0 then rx0[x]:=s[r]+1+rx0[l]
 33      else rx0[x]:=s[r];
 34      end;
 35    if lx1[l]=s[l] then
 36      begin
 37      if v[x]=1 then lx1[x]:=s[l]+1+lx1[r]
 38      else lx1[x]:=s[l];
 39      end
 40    else lx1[x]:=lx1[l];
 41    if rx1[r]=s[r] then
 42      begin
 43      if v[x]=1 then rx1[x]:=s[r]+1+rx1[l]
 44      else rx1[x]:=s[r];
 45      end;
 46    mx0[x]:=max(mx0[l],mx0[r]);
 47    if v[x]=0 then mx0[x]:=max(mx0[x],rx0[l]+lx0[r]+1);
 48    mx1[x]:=max(mx1[l],mx1[r]);
 49    if v[x]=1 then mx1[x]:=max(mx1[x],rx1[l]+lx1[r]+1);
 50  end;
 51 procedure rotate(x:longint;var k:longint);
 52  var y,z,l,r:longint;
 53  begin
 54    y:=fa[x];z:=fa[y];
 55    l:=ord(c[y,1]=x);r:=l xor 1;
 56    if y=k then k:=x else c[z,ord(c[z,1]=y)]:=x;
 57    fa[x]:=z;fa[y]:=x;fa[c[x,r]]:=y;
 58    c[y,l]:=c[x,r];c[x,r]:=y;
 59    pushup(y);pushup(x);
 60  end;
 61 procedure splay(x:longint;var k:longint);
 62  var y,z:longint;
 63  begin
 64    while x<>k do
 65     begin
 66       y:=fa[x];z:=fa[y];
 67       if y<>k then
 68        if (c[z,0]=y) xor (c[y,0]=x) then rotate(x,k)
 69        else rotate(y,k);
 70       rotate(x,k);
 71     end;
 72  end;
 73 
 74 
 75 procedure build(l,r,f:longint);
 76  var mid,x,y:longint;
 77    begin
 78     if l>r then exit;
 79     mid:=(l+r)>>1;
 80     x:=id[mid];y:=id[f];
 81     c[y,ord(mid>f)]:=x;fa[x]:=y;
 82     v[x]:=a[mid];
 83     if l=r then
 84       begin
 85       s[x]:=1;sum0[x]:=ord(v[x]=0);sum1[x]:=ord(v[x]=1);
 86       lx0:=sum0;rx0:=sum0;mx0:=sum0;
 87       lx1:=sum1;rx1:=sum1;mx1:=sum1;
 88       exit;
 89       end;
 90     build(l,mid-1,mid);build(mid+1,r,mid);
 91     pushup(x);
 92    end;
 93 procedure init;
 94  begin
 95    readln(n,m);
 96    a[1]:=-1;a[n+2]:=-1;
 97    for i:=2 to n+1 do read(a[i]);readln;
 98    for i:=1 to n+2 do id[i]:=i;
 99    build(1,n+2,0);rt:=(n+3)>>1;
100  end;
101 procedure same0(x:longint);
102  begin
103   tag[x]:=true;v[x]:=0;
104   sum0[x]:=s[x];lx0[x]:=s[x];rx0[x]:=s[x];mx0[x]:=s[x];
105   sum1[x]:=0;lx1[x]:=0;rx1[x]:=0;mx1[x]:=0;
106  end;
107 procedure same1(x:longint);
108  begin
109   tag[x]:=true;v[x]:=1;
110   sum1[x]:=s[x];lx1[x]:=s[x];rx1[x]:=s[x];mx1[x]:=s[x];
111   sum0[x]:=0;lx0[x]:=0;rx0[x]:=0;mx0[x]:=0;
112  end;
113 procedure rever(x:longint);
114  begin
115   if (x=0) or (tag[x]) then exit;
116   rev[x]:=not(rev[x]);v[x]:=v[x] xor 1;
117   swap(lx0[x],lx1[x]);
118   swap(rx0[x],rx1[x]);
119   swap(sum0[x],sum1[x]);
120   swap(mx0[x],mx1[x]);
121  end;
122 procedure pushdown(x:longint);
123  var l,r:longint;
124  begin
125   l:=c[x,0];r:=c[x,1];
126   if tag[x] then
127    begin
128    tag[x]:=false;rev[x]:=false;
129    if v[x]=0 then begin same0(l);same0(r);end
130    else begin same1(l);same1(r);end;
131    end;
132   if rev[x] then
133    begin
134    rev[x]:=false;
135    rever(l);rever(r);
136    pushup(x);
137    end;
138  end;
139 
140 function find(x,rk:longint):longint;
141  var l,r:longint;
142  begin
143    pushdown(x);l:=c[x,0];r:=c[x,1];
144    if s[l]+1=rk then exit(x)
145    else if s[l]>=rk then exit(find(l,rk))
146    else exit(find(r,rk-s[l]-1));
147  end;
148 
149 procedure split(l,r:longint;var x,y:longint);
150  begin
151    x:=find(rt,l);y:=find(rt,r);
152    splay(x,rt);splay(y,c[x,1]);
153  end;
154 procedure main;
155  begin
156    for i:=1 to  m do
157     begin
158       readln(ch,ll,rr);inc(ch);inc(ll,1);inc(rr,3);
159       split(ll,rr,x,y);
160       case ch of
161       1:same0(c[y,0]);
162       2:same1(c[y,0]);
163       3:rever(c[y,0]);
164       4:writeln(sum1[c[y,0]]);
165       5:writeln(mx1[c[y,0]]);
166       end;
167     end;
168  end;
169 begin
170   assign(input,'input.txt');assign(output,'output.txt');
171   reset(input);rewrite(output);
172   init;
173   main;
174   close(input);close(output);
175 end.
176       
View Code

 UPD:这是一份错的代码。。。

正解戳这里额:http://www.cnblogs.com/zyfzyf/p/3940159.html

posted @ 2014-08-10 12:35  ZYF-ZYF  Views(184)  Comments(1Edit  收藏  举报