x01:最大值(点修改)
总时间限制:
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范围内
题解
#include<bits/stdc++.h>
using namespace std;
long long read(){
long long ans=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
f*=(ch=='-')?-1:1;
ch=getchar();
}
while(isdigit(ch)){
ans=(ans<<3)+(ans<<1)+(ch^48);
ch=getchar();
}
return ans*f;
}
const int MAXN=1e5+5;
int a[MAXN*4];
struct SegmentTree{
int l,r;
int dat;
};
struct SegmentTree t[MAXN*4];
void build(int p,int l,int r){
t[p].l=l,t[p].r=r;
if(l==r){
t[p].dat=a[l];
return;
}
int mid=(l+r)/2;
build(p*2,l,mid);
build(p*2+1,mid+1,r);
t[p].dat=max(t[p*2].dat,t[p*2+1].dat);
}
void change(int p,int x,int v){
if(t[p].l==t[p].r){
t[p].dat=v;
return;
}
int mid=(t[p].l+t[p].r)/2;
if(x<=mid){
change(p*2,x,v);
}
else change(p*2+1,x,v);
t[p].dat=max(t[p*2].dat,t[p*2+1].dat);
}
int ask(int p,int l,int r){
if(l<=t[p].l&&r>=t[p].r) return t[p].dat;
int mid=(t[p].l+t[p].r)/2;
int val=-(1<<30);
if(l<=mid) val=max(val,ask(p*2,l,r));
if(r>mid) val=max(val,ask(p*2+1,l,r));
return val;
}
int main(){
int m=read();
for(int i=1;i<=m;i++){
a[i]=read();
}
build(1,1,m);
int n=read();
for(int i=1;i<=n;i++){
int a=read(),b=read(),c=read();
if(a==1){
change(1,b,c);
}
if(a==2){
cout<<ask(1,b,c)<<endl;
}
}
}