#include <iostream> #include <stdio.h> #include <algorithm> #define lson rt<<1,L,mid #define rson rt<<1|1,mid+1,R /* AC 水题 题意:给出n个数,两种操作 U i x 将第i个数改成x Q x y 查询[x,y]中两个数的和的最大值,这两个数不能为同一个 即只要求该区间第一大和第二大的数,他们的和即为答案 */ using namespace std; const int INF=0x3f3f3f3f; const int maxn=100005; int n,m; struct Node{ long long m1,m2; //存储该区间第一大的数和第二大的数 }tree[maxn<<2]; void pushUp(Node &rt,Node &ls,Node &rs){ if(ls.m1>rs.m1){ rt.m1=ls.m1; if(ls.m2>=rs.m1) rt.m2=ls.m2; else rt.m2=rs.m1; } else if(ls.m1==rs.m1){ rt.m1=rt.m2=ls.m1; } else{ rt.m1=rs.m1; if(rs.m2>=ls.m1) rt.m2=rs.m2; else rt.m2=ls.m1; } } void build(int rt,int L,int R){ if(L==R){ scanf("%lld",&tree[rt].m1); tree[rt].m2=-INF; return; } int mid=(L+R)>>1; build(lson); build(rson); pushUp(tree[rt],tree[rt<<1],tree[rt<<1|1]); } void update(int rt,int L,int R,int x,long long c){ if(L==R){ tree[rt].m1=c; tree[rt].m2=-INF; return; } int mid=(L+R)>>1; if(x<=mid) update(lson,x,c); else update(rson,x,c); pushUp(tree[rt],tree[rt<<1],tree[rt<<1|1]); } Node query(int rt,int L,int R,int l,int r){ if(l<=L&&R<=r){ return tree[rt]; } int mid=(L+R)>>1; Node tmp,r1,r2; if(r<=mid) tmp=query(lson,l,r); else if(l>mid) tmp=query(rson,l,r); else{ r1=query(lson,l,mid); r2=query(rson,mid+1,r); pushUp(tmp,r1,r2); } return tmp; } int main() { char str[5]; int x,y; long long v; scanf("%d",&n); build(1,1,n); scanf("%d",&m); for(int i=1;i<=m;i++){ scanf("%s",str); if(str[0]=='U'){ scanf("%d%lld",&x,&v); update(1,1,n,x,v); } else{ scanf("%d%d",&x,&y); Node ans=query(1,1,n,x,y); //cout<<ans.m1<<" "<<ans.m2<<endl; printf("%lld ",ans.m1+ans.m2); } } return 0; }