打模拟赛前写了很多次都不能过
下午敲了两遍直接就过了
嗯…重学线段树重新做人
还是比较后悔上午的暴力分没拿全
___________________________________________________补记
看了一下别的版本的线段树
空间*4
是因为通过2*n 和2*n+1来存储子节点
这样就有大量的空间浪费
为了避免这种空间浪费
caioj上这种写法 另外申请了lc rc两个数组
有效的避免了浪费
所以空间开两倍即可
大概也算是dfs序吧
空间开两倍已检验 没有re
#include<bits/stdc++.h>
#define maxn 100001
using namespace std;
template <typename T> void read(T &x){
x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
x*=f;
}
int n,m;
int a[maxn];
struct node{
int l,r,lc,rc,maxc;
}tr[maxn*2];int len;
void bt(int l,int r){
++len;int now=len;
tr[now].l=l,tr[now].r=r;
tr[now].lc=tr[now].rc=-1;
if(l==r) tr[now].maxc=a[l];
else{
int mid=(l+r)>>1;
tr[now].lc=len+1,bt(l,mid);
tr[now].rc=len+1,bt(mid+1,r);
tr[now].maxc=max(tr[tr[now].lc].maxc,tr[tr[now].rc].maxc);
}
}
void changed(int now,int x,int k){
if(tr[now].l==tr[now].r){
tr[now].maxc=k;
return;
}
int lc=tr[now].lc,rc=tr[now].rc;
int mid=(tr[now].l+tr[now].r)>>1;
if(x<=mid) changed(lc,x,k);
else if(x>=mid+1) changed(rc,x,k);
tr[now].maxc=max(tr[lc].maxc,tr[rc].maxc);
}
int findmax(int now,int l,int r){
if(l==tr[now].l&&r==tr[now].r) return tr[now].maxc;
int lc=tr[now].lc,rc=tr[now].rc;
int mid=(tr[now].l+tr[now].r)>>1;
if(r<=mid) findmax(lc,l,r);
else if(l>=mid+1) findmax(rc,l,r);
else return max(findmax(lc,l,mid),findmax(rc,mid+1,r));
}
int main(){
read(n),read(m);
for(int i=1;i<=n;++i) read(a[i]);
bt(1,n);
for(int i=1;i<=m;++i){
string a;int x,y;
cin>>a;
read(x),read(y);
if(a[0]=='C') changed(1,x,y);
else{
if(x>y) swap(x,y);
cout<<findmax(1,x,y)<<endl;
}
}
}