这道题相比较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.