5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5
5 6 5 9HintHuge input,the C function scanf() will work better than cin
线段树的基础题目之一,区间求最值,函数还是那四个,建树,更新节点信息,查询,向上更新,唯一需要注意的地方就是查询的时候,不能用if else,因为一个待查询的区间可能分布在多个小区间内,所以完全可能左右子树都查询。另外就是输入单个字符用scanf()的话,并且上面又有其他输入,一定要用getchar()吸收掉上一步输入的回车,否则会变成乱码。
#include <iostream> #include <cmath> #include <stdio.h> #include <string> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <iomanip> #include <algorithm> #include <memory.h> #define MAX 800000 using namespace std; int max(int a,int b) { return a>b?a:b; } struct Tree { int score; int Max; }tree[MAX]; void PushUp(int rt) { tree[rt].Max=max(tree[rt<<1].Max,tree[rt<<1|1].Max); } void Update(int p,int date,int l,int r,int rt) { if(l==r) { tree[rt].score=date; tree[rt].Max=date; return; } int m=(l+r)>>1; if(p<=m) Update(p,date,l,m,rt<<1); else Update(p,date,m+1,r,rt<<1|1); PushUp(rt); } void Build(int l,int r,int rt) { if(l==r) { scanf("%d",&tree[rt].score); tree[rt].Max=tree[rt].score; return; } int m=(l+r)>>1; Build(l,m,rt<<1); Build(m+1,r,rt<<1|1); PushUp(rt); } int Query(int L,int R,int l,int r,int rt) { if(L<=l&&R>=r) { return tree[rt].Max; } int ans=0; int m=(l+r)>>1; if(L<=m)//查询的时候不用else是因为可能产生多路查询 ans=max(ans,Query(L,R,l,m,rt<<1)); if(R>m) ans=max(ans,Query(L,R,m+1,r,rt<<1|1)); return ans; } int main() { int n,m; char op; int o1,o2; while(~scanf("%d%d",&n,&m)) { Build(1,n,1); while(m--) { getchar(); scanf("%c%d%d",&op,&o1,&o2); if(op=='Q') { printf("%d\n",Query(o1,o2,1,n,1)); } else if(op=='U') { Update(o1,o2,1,n,1); } } } return 0; }