-
总时间限制:
- 10000ms 单个测试点时间限制:
- 1000ms 内存限制:
- 65535kB
-
描述
-
在N(1<=n<=100000)个数A1…An组成的序列上进行M(1<=m<=100000)< span="">次操作,操作有两种:
1、表示修改A[x]为y;
2、询问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范围内
题解:
简单的线段树,用一个node数组存某个区间的最大值就行了
代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=400005;
long long n,m,step,x,y,maxx;
long long a[MAXN];
long long node[MAXN];
void build(long long L,long long R,long long rt){
if(L==R){
node[rt]=a[L];
return ;
}
long long mid=(L+R)/2;
build(L,mid,rt*2);
build(mid+1,R,rt*2+1);
node[rt]=max(node[rt*2],node[rt*2+1]);
}
void Change(long long L,long long R,long long rt){
if(L==R){
node[rt]=y;
return ;
}
long long mid=(L+R)/2;
if(x<=mid)
Change(L,mid,rt*2);
else
Change(mid+1,R,rt*2+1);
node[rt]=max(node[rt*2],node[rt*2+1]);
}
long long Sreach(long long L,long long R,long long rt){
if(x<=L&&y>=R)
return node[rt];
long long mid=(L+R)/2;
if(x<=mid)
maxx=max(maxx,Sreach(L,mid,rt*2));
if(y>mid)
maxx=max(maxx,Sreach(mid+1,R,rt*2+1));
return maxx;
}
int main(){
cin>>n;
for(int i=1;i<=n;i++)
scanf("%lld",&a[i]);
build(1,n,1);
cin>>m;
while(m--){
scanf("%lld%lld%lld",&step,&x,&y);
if(step==1)
Change(1,n,1);
else{
maxx=0;
printf("%lld\n",Sreach(1,n,1));
}
}
return 0;
}