您的位置:首页 > 其它

线段树模板

2013-11-17 11:52 232 查看
线段树其实复习的不是什么思想,主要应该是自己的代码风格与边界处理,就直接由题目来复习吧。另外,重新理解一下线段树的操作原理对于做题时很有帮助的。比赛前一定要耐心看一下每一种线段树的建树与维护方式。

pascal模板

不修改的RMQ:

例题:vijosP1514 天才的记忆

var
before,q,x,y,i,j,k,l,m,n:longint;
mc,ma,mb,sum:array[1..3000000] of longint;
tree:array[1..500001] of longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a);
exit(b);
end;
{建树}
procedure build_tree(l,r,num:longint);
var
mid:longint;
begin
if l=r then begin
ma[num]:=tree[l];
mb[num]:=tree[l];
sum[num]:=tree[l];
mc[num]:=tree[l];
exit;
end;
mid:=(l+r)>>1;
build_tree(l,mid,num<<1);
build_tree(mid+1,r,num<<1+1);
sum[num]:=sum[num<<1]+sum[num<<1+1];
ma[num]:=max(ma[num<<1],sum[num<<1]+ma[num<<1+1]);
mb[num]:=max(mb[num<<1]+sum[num<<1+1],mb[num<<1+1]);
mc[num]:=max(mc[num<<1],mc[num<<1+1]);
mc[num]:=max(mc[num],mb[num<<1]+ma[num<<1+1]);
end;
{修改}
procedure change(l,r,num:longint);
var
mid:longint;
begin
if l=r then begin
ma[num]:=y;
mb[num]:=y;
sum[num]:=y;
mc[num]:=y;
exit;
end;
mid:=(l+r)>>1;
if x<=mid  then
change(l,mid,num<<1)
else
change(mid+1,r,num<<1+1);
sum[num]:=sum[num<<1]+sum[num<<1+1];
ma[num]:=max(ma[num<<1],sum[num<<1]+ma[num<<1+1]);
mb[num]:=max(mb[num<<1]+sum[num<<1+1],mb[num<<1+1]);
mc[num]:=max(mc[num<<1],mc[num<<1+1]);
mc[num]:=max(mc[num],mb[num<<1]+ma[num<<1+1]);
end;
function query:longint;
var
mid:longint;
procedure ask(l,r,num:longint);
var
mid:longint;
begin
if (x<=l)and(r<=y) then
begin
query:=max(query,ma[num]+before);
query:=max(query,mc[num]);
before:=max(mb[num],sum[num]+before);
exit;
end;
mid:=(l+r)>>1;
if y<=mid then ask(l,mid,num<<1) else
if x>mid then ask(mid+1,r,num<<1+1) else
begin
ask(l,mid,num<<1);
ask(mid+1,r,num<<1+1);
end;
end;
begin
before:=-100000;
query:=-100000;
ask(1,n,1);
end;
begin
readln(n,m);
for i:=1 to n do
read(tree[i]);
build_tree(1,n,1);
readln;
for i:=1 to m do
begin
readln(q,x,y);
if q=1 then
begin
if x>y then
begin
q:=x;
x:=y;
y:=q;
end;
writeln(query);
end
else change(1,n,1);
end;
end.


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: