http://acm.hdu.edu.cn/showproblem.php?pid=1754
这是一道运用线段树求解简单RMQ的题目,和敌兵布阵一样,这题的跟新操作也是对点进行的,即跟新时跟新到根节点即可,无需任何技巧。注意这题也是一点为基础单位(一个点代表一个学生),所以依然是建成点树。每次跟新后自下而上的进行最大值DP,为查询节约时间!
View Code
1 #include<iostream>
2 #include<string>
3 using namespace std;
4
5 struct node
6 {
7 int l;
8 int r;
9 int max_val;
10 };
11
12 node tree[1000000];
13 int score[200001];
14 int n,m;
15
16 int max(int a,int b)
17 {
18 return a>b?a:b;
19 }
20
21 void build(int i,int l,int r)
22 {
23 tree[i].l=l;
24 tree[i].r=r;
25 if(l==r)
26 {
27 tree[i].max_val=score[l];
28 return;
29 }
30 int mid=(l+r)/2;
31 build(2*i,l,mid);
32 build(2*i+1,mid+1,r);
33 tree[i].max_val=max(tree[2*i].max_val,tree[2*i+1].max_val);
34 }
35
36 void updata(int i,int l,int r,int w)
37 {
38 if(tree[i].l>r || tree[i].r<l)
39 return;
40 if(tree[i].l>=l && tree[i].r<=r)
41 {
42 tree[i].max_val=w;
43 return;
44 }
45 updata(2*i,l,r,w);
46 updata(2*i+1,l,r,w);
47 tree[i].max_val=max(tree[2*i].max_val,tree[2*i+1].max_val);
48 }
49
50 int ans;
51
52 void find(int i,int l,int r)
53 {
54 if(tree[i].l>r || tree[i].r<l)
55 return;
56 if(tree[i].l>=l && tree[i].r<=r)
57 {
58 ans=max(ans,tree[i].max_val);
59 return;
60 }
61 find(2*i,l,r);
62 find(2*i+1,l,r);
63 }
64
65 int main()
66 {
67 int i,a,b;
68 char c;
69 freopen("in.txt","r",stdin);
70 while(scanf("%d%d",&n,&m)==2)
71 {
72 for(i=1;i<=n;i++)
73 scanf("%d",&score[i]);
74 build(1,1,n);
75 for(i=0;i<m;i++)
76 {
77 scanf("%*c");
78 scanf("%c%d%d",&c,&a,&b);
79 if(c=='Q')
80 {
81 ans=0;
82 find(1,a,b);
83 printf("%d\n",ans);
84 }
85 else if(c=='U')
86 {
87 updata(1,a,a,b);
88 }
89 }
90 }
91 return 0;
92 }