Description
在N(1<=N<=100000)个数A1…An组成的序列上进行M(1<=M<=100000)次操作,操作有两种:
1 x y:表示修改A[x]为y;
2 x y:询问x到y之间的最大值。
Input
第一行输入N(1<=N<=100000),表示序列的长度,接下来N行输入原始序列;接下来一行输入M(1<=M<=100000)表示操作的次数,接下来M行,每行为1 x y或2 x y
Output
对于每个操作(2)输出对应的答案。
Sample Input
5
1
2
3
4
5
3
2 1 4
1 3 5
2 2 4
Sample Output
4
5
Data Constraint
Hint
【限制】
保证序列中的所有的数都在longint范围内
Solution
直接线段树维护区间最大值+单点修改即可。
Code1
const maxn=100000;
var n,m,i,j,k,x,y,ans:longint;
a:array[1..maxn]of longint;
tree:array[1..4*maxn]of longint;
function max(x,y:longint):longint;
begin
if x>y then max:=x else max:=y;
end;
procedure maketree(x,st,en:longint);
var m:longint;
begin
if st=en then tree[x]:=a[st]
else begin
m:=(st+en)shr 1;
maketree(x+x,st,m);
maketree(x+x+1,m+1,en);
tree[x]:=max(tree[x+x],tree[x+x+1]);
end;
end;
procedure change(x,st,en,p,value:longint);
var m:longint;
begin
if st=en then tree[x]:=value
else begin
m:=(st+en)shr 1;
if p<=m then change(x+x,st,m,p,value)
else change(x+x+1,m+1,en,p,value);
tree[x]:=max(tree[x+x],tree[x+x+1]);
end;
end;
procedure find(x,st,en,l,r:longint);
var m:longint;
begin
if (st=l)and(en=r) then ans:=max(ans,tree[x])
else begin
m:=(st+en)shr 1;
if r<=m then find(x+x,st,m,l,r)
else if l>m then find(x+x+1,m+1,en,l,r)
else begin
find(x+x,st,m,l,m);
find(x+x+1,m+1,en,m+1,r);
end;
end;
end;
begin
assign(input,'max.in');reset(input);
assign(output,'max.out');rewrite(output);
readln(n);
for i:=1 to n do readln(a[i]);
maketree(1,1,n);
readln(m);
for i:=1 to m do begin
readln(k,x,y);
case k of
1:change(1,1,n,x,y);
2:begin
ans:=-maxlongint;
find(1,1,n,x,y);
writeln(ans);
end;
end;
end;
close(input);
close(output);
end.
Code2
#include<cstdio>
using namespace std;
int a[100001],f[500001],ans;
int n,m,k,x,y;
int max(int a,int b)
{
if (a>b) return a;
else return b;
}
void build(int x,int l,int r)
{
int m;
if (l==r) f[x]=a[l];
else
{
m=(l+r)/2;
build(x*2,l,m);
build(x*2+1,m+1,r);
f[x]=max(f[x*2],f[x*2+1]);
}
}
void change(int x,int l,int r,int k)
{
int m;
if (l==r) f[x]=y;
else
{
m=(l+r)/2;
if (k<=m) change(x*2,l,m,k);
else change(x*2+1,m+1,r,k);
f[x]=max(f[x*2],f[x*2+1]);
}
}
void find(int x,int s,int t,int l,int r)
{
int m;
if ((s==l)and(t==r)) ans=max(ans,f[x]);
else
{
m=(s+t)/2;
if (r<=m) find(x*2,s,m,l,r);
else if (l>m) find(x*2+1,m+1,t,l,r);
else
{
find(x*2,s,m,l,m);
find(x*2+1,m+1,t,m+1,r);
}
}
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++) scanf("%d",&a[i]);
build(1,1,n);
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&k,&x,&y);
if (k==1) change(1,1,n,x);
else
{
ans=-2147483647;
find(1,1,n,x,y);
printf("%d\n",ans);
}
}
return 0;
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/81914089