【题意】给定区间求最大值
【分析】线段树单点更新
【代码】
#include<cstdio> #include<iostream> using namespace std; const int maxn=1<<21; const int INF=0x3fffffff; int Max=0; int mid; struct Node { int l,r;//左孩子,右孩子 int value; }N[maxn]; int p[200005];//记录标号 void build(int i,int left ,int right)//区间[left,right],节点标号i { N[i].l=left; N[i].r=right; N[i].value=0; if(left==right) { p[left]=i; return; } mid=(left+right)>>1; build(i<<1,left,mid); build(1+(i<<1),mid+1,right); } void update(int i)//从下往上更新单节点 { if(i==1) return ; int pi=i/2; int left=pi<<1; int right=(pi<<1)+1; N[pi].value=max(N[left].value,N[right].value); update(i/2); } void query(int i,int left,int right)//从上往下查询节点 { if(N[i].l==left&&N[i].r==right) { Max=max(N[i].value,Max); return; } i<<=1; if(N[i].r>=left&&N[i].r>=right) query(i,left,right); else if(N[i].r>=left&&N[i].r<=right) query(i,left,N[i].r); i++; if(N[i].l<=right&&N[i].l<=left) query(i,left,right); else if(N[i].l<=right&&N[i].l>=left) query(i,N[i].l,right); } int main (void) { int n,m; int A,B; char c[2]; while(scanf("%d%d",&n,&m)==2) { build(1,1,n); for(int i=1;i<=n;i++) { scanf("%d",& N[p[i]].value); update(p[i]); } for(int i=1;i<=m;i++) { scanf("%s%d%d",c,&A,&B); if(c[0]=='Q') { Max=0; query(1,A,B); printf("%d ",Max); } else { N[p[A]].value=B; update(p[A]); } } } return 0; }