这道题相比较bzoj3223只不过多了一个区间加上一个数,这显然还是类似的

和线段树经典的打标记类似

  1 const inf=-2147483647;
  2       sroot=-1;
  3 var son:array[-1..50010,1..2] of longint;
  4     fa,maxx,count,a,lazy:array[-1..50010] of longint;
  5     v:array[0..50010] of boolean;
  6     ch,i,n,m,l,r,z,root:longint;
  7 
  8 function max(a,b:longint):longint;
  9   begin
 10     if a>b then exit(a) else exit(b);
 11   end;
 12 
 13 procedure swap(var a,b:longint);
 14   var c:longint;
 15   begin
 16     c:=a;
 17     a:=b;
 18     b:=c;
 19   end;
 20 
 21 procedure work_add(x,w:longint);
 22   begin
 23     a[x]:=a[x]+w;
 24     lazy[x]:=lazy[x]+w;
 25     maxx[x]:=maxx[x]+w;
 26   end;
 27 
 28 procedure change(x:longint);
 29   begin
 30     swap(son[x,1],son[x,2]);
 31     v[x]:=not v[x];
 32   end;
 33 
 34 procedure pushdown(x:longint);
 35   var l,r:longint;
 36   begin
 37     l:=son[x,1];
 38     r:=son[x,2];
 39     if v[x] then
 40     begin
 41       if l<>-1 then change(l);
 42       if r<>-1 then change(r);
 43       v[x]:=false;
 44     end;
 45     if lazy[x]<>0 then
 46     begin
 47       if l<>-1 then work_add(l,lazy[x]);
 48       if r<>-1 then work_add(r,lazy[x]);
 49       lazy[x]:=0;
 50     end;
 51   end;
 52 
 53 procedure updata(i:longint);
 54   begin
 55     count[i]:=count[son[i,1]]+count[son[i,2]]+1;
 56     maxx[i]:=max(max(maxx[son[i,1]],maxx[son[i,2]]),a[i]);
 57   end;
 58 
 59 function find(x:longint):longint;
 60   var p:longint;
 61   begin
 62     p:=root;
 63     while true do
 64     begin
 65       pushdown(p);
 66       if count[son[p,1]]+1=x then exit(p);
 67       if count[son[p,1]]+1>x then p:=son[p,1]
 68       else begin
 69         x:=x-count[son[p,1]]-1;
 70         p:=son[p,2];
 71       end;
 72     end;
 73   end;
 74 
 75 procedure rotate(x,w:longint);
 76   var y:longint;
 77   begin
 78     pushdown(x);
 79     y:=fa[x];
 80     if fa[y]<>sroot then
 81     begin
 82       if son[fa[y],1]=y then
 83         son[fa[y],1]:=x
 84       else son[fa[y],2]:=x;
 85     end;
 86     fa[x]:=fa[y];
 87     if son[x,w]<>-1 then fa[son[x,w]]:=y;
 88     son[y,3-w]:=son[x,w];
 89     son[x,w]:=y;
 90     fa[y]:=x;
 91     updata(y);
 92     updata(x);
 93   end;
 94 
 95 procedure splay(x,f:longint);
 96   var y:longint;
 97   begin
 98     while fa[x]<>f do
 99     begin
100       y:=fa[x];
101       if fa[y]=f then
102         if x=son[y,1] then rotate(x,2) else rotate(x,1)
103       else
104         if y=son[fa[y],1] then
105           if x=son[y,1] then
106           begin
107             rotate(y,2);
108             rotate(x,2);
109           end
110           else begin
111             rotate(x,1);
112             rotate(x,2);
113           end
114         else
115           if x=son[y,1] then
116           begin
117             rotate(x,2);
118             rotate(x,1);
119           end
120           else begin
121             rotate(y,1);
122             rotate(x,1);
123           end;
124     end;
125     updata(x);
126     if f=sroot then root:=x;
127   end;
128 
129 procedure add(l,r,w:longint);
130   var p:longint;
131   begin
132     p:=find(l);
133     splay(p,sroot);
134     p:=find(r+2);
135     splay(p,root);
136     p:=son[son[root,2],1];
137     work_add(p,w);
138   end;
139 
140 procedure reverse(l,r:longint);
141   var p:longint;
142   begin
143     p:=find(l);
144     splay(p,sroot);
145     p:=find(r+2);
146     splay(p,root);
147     p:=son[son[root,2],1];
148     change(p);
149   end;
150 
151 function ask(l,r:longint):longint;
152   var p:longint;
153   begin
154     p:=find(l);
155     splay(p,sroot);
156     p:=find(r+2);
157     splay(p,root);
158     p:=son[son[root,2],1];
159     exit(maxx[p]);
160   end;
161 
162 function build(l,r:longint):longint;
163   var m:longint;
164   begin
165     m:=(l+r) shr 1;
166     build:=m;
167     if l+1<=m then
168     begin
169       son[m,1]:=build(l,m-1);
170       fa[son[m,1]]:=m;
171     end;
172     if r-1>=m then
173     begin
174       son[m,2]:=build(m+1,r);
175       fa[son[m,2]]:=m;
176     end;
177     updata(m);
178   end;
179 
180 begin
181   readln(n,m);
182   fillchar(son,sizeof(son),255);
183   fillchar(lazy,sizeof(lazy),0);
184   fillchar(a,sizeof(a),0);
185   fillchar(v,sizeof(v),false);
186   a[-1]:=inf;  //注意这个-1很重要,在splay过程,我有的地方没有判断子节点是否存在
187   maxx[-1]:=inf;
188   inc(n);
189   root:=build(0,n);
190   fa[root]:=sroot;
191   for i:=1 to m do
192   begin
193     read(ch,l,r);
194     if ch=1 then
195     begin
196       readln(z);
197       add(l,r,z);
198     end
199     else begin
200       readln;
201       if ch=2 then reverse(l,r)
202       else writeln(ask(l,r));
203     end;
204   end;
205 end.
View Code

 

posted on 2015-01-09 21:42  acphile  阅读(126)  评论(0编辑  收藏  举报