bzoj 1251 裸splay
裸的splay,只需要注意 max[-1]:=-maxlongint 就行了,否则在update的时候子节点的
max值会在max[-1]里选
/**************************************************************
Problem:
1251
User: BLADEVIL
Language: Pascal
Result: Accepted
Time:
16008
ms
Memory:
3448
kb
****************************************************************/
//By BLADEVIL
const
sroot =-
1
;
var
n, m :
longint
;
i :
longint
;
a, father :
array
[-
1..100010
]
of
longint
;
k, l, r, v :
longint
;
root :
longint
;
max, size, tree :
array
[-
1..100010
]
of
longint
;
val
:
array
[-
1..100010
]
of
longint
;
flag :
array
[-
1..100010
]
of
boolean
;
son :
array
[-
1..100010
,
0..1
]
of
longint
;
procedure
swap(
var
a,b:
longint
);
var
c :
longint
;
begin
c:=a; a:=b; b:=c;
end
;
function
get_max(a,b:
longint
):
longint
;
begin
if
a>b
then
exit(a)
else
exit(b);
end
;
procedure
renew_add(x,v:
longint
);
begin
inc(tree[x],v); inc(
val
[x],v); inc(max[x],v);
end
;
procedure
renew_reverse(x:
longint
);
begin
swap(son[x,
1
],son[x,
0
]);
flag[x]:=
not
flag[x];
end
;
procedure
update(x:
longint
);
begin
//if x=sroot then exit;
max[x]:=get_max(tree[x],get_max(max[son[x,
1
]],max[son[x,
0
]]));
size[x]:=size[son[x,
1
]]+size[son[x,
0
]]+
1
;
end
;
function
build(l,r:
longint
):
longint
;
var
mid :
longint
;
begin
mid:=(r+l)
div
2
;
build:=mid;
tree[mid]:=a[mid];
if
l+
1
<=mid
then
begin
son[mid,
0
]:=build(l,mid-
1
);
father[son[mid,
0
]]:=mid;
end
;
if
mid<=r-
1
then
begin
son[mid,
1
]:=build(mid+
1
,r);
father[son[mid,
1
]]:=mid;
end
;
update(mid);
end
;
procedure
push_down(x:
longint
);
var
l, r :
longint
;
begin
l:=son[x,
0
]; r:=son[x,
1
];
if
flag[x]
then
begin
if
l<>-
1
then
renew_reverse(l);
if
r<>-
1
then
renew_reverse(r);
flag[x]:=
false
;
end
;
if
val
[x]<>
0
then
begin
if
l<>-
1
then
renew_add(l,
val
[x]);
if
r<>-
1
then
renew_add(r,
val
[x]);
val
[x]:=
0
;
end
;
end
;
function
find(x:
longint
):
longint
;
var
t :
longint
;
begin
t:=root;
while
true
do
begin
push_down(t);
if
size[son[t,
0
]]+
1
=x
then
exit(t);
if
size[son[t,
0
]]+
1
>x
then
t:=son[t,
0
]
else
begin
dec(x,size[son[t,
0
]]+
1
);
t:=son[t,
1
];
end
;
end
;
end
;
procedure
rotate(x,y:
longint
);
var
f :
longint
;
begin
push_down(x);
f:=father[x];
father[son[x,y
xor
1
]]:=f;
son[f,y]:=son[x,y
xor
1
];
if
f=root
then
root:=x
else
if
f=son[father[f],
0
]
then
son[father[f],
0
]:=x
else
son[father[f],
1
]:=x;
father[x]:=father[f];
father[f]:=x;
son[x,y
xor
1
]:=f;
update(f);
update(x);
end
;
procedure
splay(x,y:
longint
);
var
u, v :
longint
;
begin
while
father[x]<>y
do
begin
if
father[father[x]]=y
then
rotate(x,ord(x=son[father[x],
1
]))
else
begin
if
son[father[x],
0
]=x
then
u:=
1
else
u:=-
1
;
if
son[father[father[x]],
0
]=father[x]
then
v:=
1
else
v:=-
1
;
if
u*v=
1
then
begin
rotate(father[x],ord(x=son[father[x],
1
]));
rotate(x,ord(x=son[father[x],
1
]));
end
else
begin
rotate(x,ord(x=son[father[x],
1
]));
rotate(x,ord(x=son[father[x],
1
]));
end
;
end
;
end
;
update(x);
end
;
procedure
add(l,r,v:
longint
);
var
p :
longint
;
begin
p:=find(l);splay(p,sroot);
p:=find(r+
2
);splay(p,root);
p:=son[son[root,
1
],
0
];
renew_add(p,v);
end
;
procedure
reverse(l,r:
longint
);
var
p :
longint
;
begin
p:=find(l);splay(p,sroot);
p:=find(r+
2
);splay(p,root);
p:=son[son[root,
1
],
0
];
renew_reverse(p);
end
;
function
ask_max(l,r:
longint
):
longint
;
var
p :
longint
;
begin
p:=find(l); splay(p,sroot);
p:=find(r+
2
); splay(p,root);
p:=son[son[root,
1
],
0
];
ask_max:=max[p];
end
;
begin
fillchar(son,sizeof(son),
255
);
read(n,m);
max[-
1
]:=-maxlongint;
for
i:=
1
to
n
do
a[i]:=
0
;
inc(n);
root:=build(
0
,n);
father[root]:=sroot;
for
i:=
1
to
m
do
begin
read(k);
if
k=
1
then
begin
read(l,r,v);
add(l,r,v);
end
else
begin
read(l,r);
if
k=
2
then
reverse(l,r)
else
writeln
(ask_max(l,r));
end
;
end
;
end
.