【线段树】最大值

题目描述
在N(1<=N<=100000)个数A1…An组成的序列上进行M(1<=M<=100000)次操作,操作有两种:
(1)1 x y:表示修改A[x]为y;
(1)2 x y:询问x到y之间的最大值。

输入
第一行输入N(1<=N<=100000),表示序列的长度,接下来N行输入原始序列;接下来一行输入M(1<=M<=100000)表示操作的次数,接下来M行,每行为1 x y或2 x y

输出
对于每个操作(2)输出对应的答案。

样例输入
5
1
2
3
4
5
3
2 1 4
1 3 5
2 2 4

样例输出
4
5

数据范围限制

提示

【限制】

保证序列中的所有的数都在longint范围内
.
.
.
.
.
.
.
.

程序:
uses math;
var
n,i,j,kind,x,y,m:longint;
a,f:array[0..300000]of longint;
procedure tree(v,l,r:longint);
var
mid:longint;
begin
    mid:=(l+r) div 2;
    if l<r then
    begin
        tree(v*2,l,mid);
        tree(v*2+1,mid+1,r);
    end else
    begin
        f[v]:=a[l];
        exit;
    end;
    f[v]:=max(f[v*2],f[v*2+1]);
end;
procedure change(v,l,r,x,y:longint);
var
mid:longint;
begin
    mid:=(l+r) div 2;
    if l=r then
    begin
        f[v]:=y;
        exit;
    end;
    if x<=mid then change(v*2,l,mid,x,y) else change(v*2+1,mid+1,r,x,y);
    f[v]:=max(f[v*2],f[v*2+1])
end;
function find(v,l,r,x,y:longint):longint;
var
mid:longint;
begin
    mid:=(l+r) div 2;
    if (x=l)and(y=r) then exit(f[v]);
    if (x<=mid)and(y<=mid) then exit(find(v*2,l,mid,x,y));
    if (x<=mid)and(y>mid) then exit(max(find(v*2,l,mid,x,mid),find(v*2+1,mid+1,r,mid+1,y)));
    if (x>mid)and(y>mid) then exit(find(v*2+1,mid+1,r,x,y));
end;
begin
    readln(n);
    for i:=1 to n do
    readln(a[i]);
    tree(1,1,n);
    readln(m);
    for i:=1 to m do
    begin
        readln(kind,x,y);
        if kind=1 then change(1,1,n,x,y) else writeln(find(1,1,n,x,y));
    end;
end.

posted @ 2018-02-06 11:10  银叶草  阅读(168)  评论(0编辑  收藏  举报
Live2D