题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
题意:给出n个数字m次操作,操作分为2种,更新某一个数的大小和询问某一区间的最大值
思路:很经典的线段树,单点更新以及查询区间,刚学习线段树按照别人的思路已经写过一次了,这次写的应该更贴近自己的想法
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define Maxn 200030 using namespace std; int s[Maxn]; char op[10]; struct Tree { int l,r,date; }tree[Maxn*3]; void build(int root,int l,int r) { tree[root].l=l; tree[root].r=r; if (l==r) { tree[root].date=s[l]; return; } int mid=(l+r)>>1; build(root<<1,l,mid); build(root<<1|1,mid+1,r); tree[root].date=max(tree[root<<1].date,tree[root<<1|1].date); } void update(int root,int tar,int val) { if (tar>=tree[root].l && tar<=tree[root].r) { if (tree[root].l==tree[root].r) { tree[root].date=val; return; } int mid=(tree[root].l+tree[root].r)>>1; update(root<<1,tar,val); update(root<<1|1,tar,val); tree[root].date=max(tree[root<<1].date,tree[root<<1|1].date); } return; } int que(int root,int l,int r) { int mid=(tree[root].l+tree[root].r)>>1; if (l==tree[root].l && r==tree[root].r) return tree[root].date; else if (r<=mid) return que(root<<1,l,r); else if (l>mid) return que(root<<1|1,l,r); else return max(que(root<<1,l,mid),que(root<<1|1,mid+1,r)); } int main() { int n,m; while (scanf("%d%d",&n,&m)!=EOF) { for (int i=1;i<=n;i++) { scanf("%d",&s[i]); } build(1,1,n); for (int i=0;i<m;i++) { int a,b; scanf("%s%d%d",&op,&a,&b); if (op[0]=='Q') { printf("%d\n",que(1,a,b)); } else { update(1,a,b); } } } }