题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
用这道基础题来回顾一下线段树的基本用法,此题很明显是单点更新,区间查询,更新的方式也很简单只是值的定向改变,模板题。
一些线段树的稍微高级一点的用法可能牵扯的稍微少一些,或者说灵活性的用法,因为线段树节点存的值不一样可以解决很多稀奇古怪的问题。
再就是由于是单点简单更新,也没有用到pushdown或者是pushup操作,也不用在更新中去设置一些优化,过一遍代码,之后再写几道线段树的难题。
1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #include<string.h> 5 #include<cmath> 6 #include<stdio.h> 7 using namespace std; 8 #define zuo root*2 9 #define you root*2+1 10 #define INF 0x3f3f3f3f 11 #define ll long long 12 //#pragma warning(disable:4996) 13 ll num[1000005]; 14 ll max(ll a,ll b) 15 { 16 if(a>b) 17 return a; 18 return b; 19 } 20 struct node { 21 ll val; 22 ll m; 23 }t[4000005]; 24 25 void build(ll root, ll l, ll r) 26 { 27 if (l == r) 28 t[root].val = num[l]; 29 else 30 { 31 ll mid = (l + r) / 2; 32 build(zuo, l, mid); 33 build(you, mid + 1, r); 34 t[root].val = max(t[zuo].val,t[you].val); 35 } 36 } 37 38 ll query(ll root, ll l, ll r, ll ql, ll qr) 39 { 40 if (l > qr || r < ql) 41 return 0; 42 //pushdown(root, r - l + 1); 43 if (l >= ql&& r <= qr) 44 return t[root].val; 45 ll mid = (l + r) / 2; 46 return max(query(zuo, l, mid, ql, qr),query(you, mid + 1, r, ql, qr)); 47 } 48 49 void update(ll root, ll l, ll r, ll ul, ll ur, ll add) 50 { 51 if (l > ur || r < ul) 52 return; 53 if (l >= ul &&r <= ur) 54 { 55 t[root].val = add; 56 return; 57 } 58 //pushdown(root, r - l + 1); 59 ll mid = (l + r) / 2; 60 update(zuo, l, mid, ul, ur, add); 61 update(you, mid + 1, r, ul, ur, add); 62 t[root].val =max(t[zuo].val,t[you].val); 63 } 64 65 int main() 66 { 67 ll n, m; 68 while (~scanf("%lld%lld", &n, &m)) 69 { 70 for (ll i = 1;i <= n;i++) 71 scanf("%lld", &num[i]); 72 build(1, 1, n); 73 char s; 74 ll a, b, c; 75 for (ll i = 0;i < m;i++) 76 { 77 getchar(); 78 scanf("%c%lld%lld", &s, &a, &b); 79 if (s == 'Q') 80 cout << query(1, 1, n, a, b) << endl; 81 else 82 update(1, 1, n, a, a, b); 83 } 84 } 85 }