HDU1754 && HDU1166 线段树模板题
HDU1754
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1754
题目分析:对于给出的一个很长的区间,对其进行单点更新值和区间求最大值的操作,由于查询的区间很大,且查询次数多,这里用线段树求解将是十分合适的
注意点:1.对于存放线段树的数组大小需要开大一些
2.对于c语言的字符输入%c之前需要加一个空格保证输入准确
1 #include<iostream> 2 #include<string.h> 3 using namespace std; 4 5 const int N = 200005; 6 int grade[N]; 7 int tree[N<<2]; //这里建立的树的数组大小需要是N的4倍 否则不够用 8 int n, m; 9 10 int max(int a, int b){ 11 if(a > b) return a; 12 else return b; 13 } 14 15 void build_tree(int start, int end, int node){ //线段树的建立 16 if(start == end){ 17 tree[node] = grade[start]; 18 }else{ 19 int mid = (start + end) / 2; 20 int left_node = node*2; 21 int right_node = node*2+1; 22 23 build_tree(start, mid, left_node); 24 build_tree(mid+1, end, right_node); 25 tree[node] = max(tree[left_node], tree[right_node]); 26 } 27 } 28 29 void update_tree(int start, int end, int node, int index, int value){ //单点更新值 30 if(start == end){ 31 tree[node] = value; 32 }else{ 33 int mid = (start + end) / 2; 34 int left_node = node*2; 35 int right_node = node*2+1; 36 37 if(index <= mid) 38 update_tree(start, mid, left_node, index, value); 39 else 40 update_tree(mid+1, end, right_node, index, value); 41 tree[node] = max(tree[left_node], tree[right_node]); 42 } 43 } 44 45 int search_tree(int start, int end, int node, int l, int r){ //区间查询最大值 46 if(l > end || r < start){ 47 return 0; 48 }else if(l <= start && r >= end){ 49 return tree[node]; 50 }else if(start == end){ //这里的个递归出口放在后面是有原因的,有可能存在start==end 但是l和r根本和start end没有交集的情况,所以先判去了后者 51 return tree[node]; 52 } 53 int mid = (start + end) / 2; 54 int left_node = node*2; 55 int right_node = node*2+1; 56 57 int left_max = search_tree(start, mid, left_node, l, r); 58 int right_max = search_tree(mid+1, end, right_node, l, r); 59 int ans = max(left_max, right_max); 60 return ans; 61 } 62 63 int main(){ 64 while(scanf("%d%d", &n, &m) != EOF){ 65 for(int i = 1; i <= n; i++) 66 scanf("%d", &grade[i]); 67 build_tree(1, n, 1); 68 for(int i = 1; i <= m; i++){ 69 char c; 70 int a, b; 71 scanf(" %c %d %d", &c, &a, &b); //对于c语言的输入字符在%c之前需要一个空格,否则c就读取不到需要的字符了 72 if(c == 'U') update_tree(1, n, 1, a, b); 73 else{ 74 int ans = search_tree(1, n, 1, a, b); 75 printf("%d\n", ans); 76 } 77 } 78 } 79 return 0; 80 }
HDU1166
题目分析:
也是一题线段树的模板题,单点更新和区间查询求和(本质上和区间求最大值是一样的)
代码:
1 #include<iostream> 2 #include<string> 3 #include<string.h> 4 using namespace std; 5 6 const int N = 500005; 7 int peo[N]; 8 int tree[N<<2]; 9 10 void build_tree(int start, int end, int node){ 11 if(start == end){ 12 tree[node] = peo[start]; 13 }else{ 14 int mid = (start + end) / 2; 15 int left_node = node*2; 16 int right_node = node*2+1; 17 18 build_tree(start, mid, left_node); 19 build_tree(mid+1, end, right_node); 20 tree[node] = tree[left_node] + tree[right_node]; 21 } 22 } 23 24 void update_tree(int start, int end, int node, int index, int value){ 25 if(start == end){ 26 tree[node] += value; 27 }else{ 28 int mid = (start + end) / 2; 29 int left_node = node*2; 30 int right_node = node*2+1; 31 32 if(index <= mid) 33 update_tree(start, mid, left_node, index, value); 34 else 35 update_tree(mid+1, end, right_node, index, value); 36 tree[node] = tree[left_node] + tree[right_node]; 37 } 38 } 39 40 int query_tree(int start, int end, int node, int l, int r){ 41 if(end < l || start > r){ 42 return 0; 43 }else if(start >= l && end <= r){ 44 return tree[node]; 45 }else if(start == end){ 46 return tree[node]; 47 } 48 int mid = (start + end) / 2; 49 int left_node = node*2; 50 int right_node = node*2+1; 51 52 int left_sum = query_tree(start, mid, left_node, l, r); 53 int right_sum = query_tree(mid+1, end, right_node, l, r); 54 int ans = left_sum + right_sum; 55 return ans; 56 } 57 58 int main(){ 59 int t; 60 scanf("%d", &t); 61 int cnt = 1; 62 while(t--){ 63 printf("Case %d:\n", cnt++); 64 int n; 65 scanf("%d", &n); 66 for(int i = 1; i <= n; i++) 67 scanf("%d", &peo[i]); 68 build_tree(1, n, 1); 69 string s; 70 int a, b; 71 while(cin>>s){ 72 if(s == "End") break; 73 scanf("%d%d", &a, &b); 74 if(s == "Query"){ 75 int ans = query_tree(1, n, 1, a, b); 76 printf("%d\n", ans); 77 } 78 if(s == "Add"){ 79 update_tree(1, n, 1, a, b); 80 } 81 if(s == "Sub"){ 82 update_tree(1, n, 1, a, -b); 83 } 84 } 85 } 86 return 0; 87 }
如果有任何意见请在评论区积极留言