HDU 1754 线段树入门解题报告
---恢复内容开始---
题意:给定区间,每个人的成绩, Q次询问,求每次询问区间中的最大值
思路:构造线段树
代码:
#include<stdio.h> #include<algorithm> #include<string> #include<iostream> using namespace std; int n, m, ans; string str; struct Tree { int left, right, maxx; }tree[200000 * 4]; //线段树开4倍空间 void build(int left, int right, int k) { tree[k].left = left, tree[k].right = right; if(left == right) { scanf("%d", &tree[k].maxx); return ; } int mid = (left + right) / 2; build(left, mid, 2 * k); build(mid + 1, right, 2 * k + 1); tree[k].maxx = max(tree[2 * k].maxx, tree[2 * k + 1].maxx); //向上回溯最大值记录 } void update(int find_node, int up_num, int k)//单点修改 { if(tree[k].left == find_node && tree[k].right == find_node) { tree[k].maxx = up_num; return ; } int mid = (tree[k].left + tree[k].right) / 2; if(find_node <= mid) update(find_node, up_num, 2 * k); else update(find_node, up_num, 2 * k + 1); //修改过后回溯修改最大值 tree[k].maxx = max(tree[2 * k].maxx, tree[2 * k + 1].maxx); } void query(int find_left, int find_right, int k)//区间查询取最大值 { if(find_left == tree[k].left && find_right == tree[k].right) { ans = max(ans, tree[k].maxx); return ; } int mid = (tree[k].left + tree[k].right) / 2; if(find_right <= mid) query(find_left, find_right, 2 * k); else if(find_left > mid) query(find_left, find_right, 2 * k + 1); else { query(find_left, mid, 2 * k); query(mid + 1, find_right, 2 * k + 1); } } int main() { int a, b; while(scanf("%d%d", &n, &m)!=EOF) { build(1, n, 1); for(int i = 1; i <= m; i ++) { cin >> str; if(str == "U") { scanf("%d%d", &a, &b); update(a, b, 1); } else { ans = -1; scanf("%d%d", &a, &b); query(a, b, 1); printf("%d\n", ans); } } } return 0; }