CDOJ1324-卿学姐与公主 【线段树点更新】
http://acm.uestc.edu.cn/#/problem/show/1324
卿学姐与公主
Time Limit: 2000/1000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others)
某日,百无聊赖的卿学姐打开了某11区的某魔幻游戏
在这个魔幻的游戏里,生活着一个美丽的公主,但现在公主被关押在了魔王的城堡中。
英勇的卿学姐拔出利刃冲向了拯救公主的道路。
走过了荒野,翻越了高山,跨过了大洋,卿学姐来到了魔王的第一道城关。
在这个城关面前的是魔王的精锐部队,这些士兵成一字排开。
卿学姐的武器每次只能攻击一个士兵,并造成一定伤害,卿学姐想知道某时刻从L
到R
这个区间内,从开始到现在累计受伤最严重的士兵受到的伤害。
最开始每个士兵的受到的伤害都是0
Input
第一行两个整数N,Q表示总共有N个士兵编号从1到N,和Q个操作。接下来Q行,每行三个整数,首先输入一个t,如果t是1,那么输入p,x,表示卿学姐攻击了p这个位置的士兵,并造成了x的伤害。如果t是2,那么输入L,R,表示卿学姐想知道现在[L,R]闭区间内,受伤最严重的士兵受到的伤害。
1≤N≤100000
1≤Q≤100000
1≤p≤N
1≤x≤100000
1≤L≤R≤N1≤L≤R≤
Output
对于每个询问,回答相应的值
Sample input and output
Sample Input | Sample Output |
---|---|
5 4 2 1 2 1 2 4 1 3 5 2 3 3 |
0 5 |
思路:线段树 点更新
代码:
1 #include <fstream> 2 #include <iostream> 3 using namespace std; 4 5 #define MAX 100005 6 #define ll long long int 7 8 class SegmentTree 9 { 10 private: 11 int n; 12 struct Node 13 { 14 int left, right, mid; 15 ll maxval; 16 Node (): maxval(0) 17 {} 18 }*tree; 19 public: 20 SegmentTree (int n): n(n) 21 { 22 tree = new Node[n<<2]; 23 } 24 ~SegmentTree () 25 { 26 delete []tree; 27 } 28 void Build (); 29 void Update (int id, int subid, int val); 30 ll Search (int id, int left, int right); 31 }; 32 void SegmentTree::Build () //非递归,由于叶子只能出现在树的最后两层,故而可以以tree[i].left < n作为循环条件进行非递归操作。需要说明的是,这里把最后一层的多余内存也初始化了,不过不影响全局。 33 { 34 int t1; 35 tree[1].left = 1; 36 tree[1].right = n; 37 tree[1].mid = (n + 1) >> 1; 38 for (int i = 1; tree[i].left < n; i++) 39 { 40 if (tree[i].left < tree[i].right) 41 { 42 t1 = i << 1; 43 tree[t1].left = tree[i].left; 44 tree[t1].right = tree[i].mid; 45 tree[t1].mid = (tree[t1].left + tree[t1].right) >> 1; 46 t1++; 47 tree[t1].left = tree[i].mid + 1; 48 tree[t1].right = tree[i].right; 49 tree[t1].mid = (tree[t1].left + tree[t1].right) >> 1; 50 } 51 } 52 } 53 void SegmentTree::Update (int id, int subid, int val) 54 { 55 if (tree[id].left == tree[id].right) 56 { 57 tree[id].maxval += val; 58 } 59 else if (tree[id].mid >= subid) 60 { 61 Update(id << 1, subid, val); 62 tree[id].maxval = max(tree[id << 1].maxval, tree[id].maxval); 63 } 64 else if (tree[id].mid < subid) 65 { 66 Update((id << 1)|1, subid, val); 67 tree[id].maxval = max(tree[id].maxval, tree[(id << 1)|1].maxval); 68 } 69 } 70 ll SegmentTree::Search (int id, int left, int right) 71 { 72 if (tree[id].left == left && tree[id].right == right) 73 { 74 return tree[id].maxval; 75 } 76 else if (tree[id].mid >= right) 77 { 78 return Search(id << 1, left, right); 79 } 80 else if (tree[id].mid < left) 81 { 82 return Search((id << 1)|1, left, right); 83 } 84 else 85 { 86 return max(Search(id << 1, left, tree[id].mid), Search((id << 1)|1, tree[id].mid + 1, right)); 87 } 88 } 89 90 int main () 91 { 92 //freopen("D:\\input.in","r",stdin); 93 int n, q, t, p, x; 94 scanf ("%d %d", &n, &q); 95 SegmentTree lv(n); 96 lv.Build(); 97 for (int i = 0; i < q; i++) 98 { 99 scanf ("%d %d %d", &t, &p, &x); 100 if (t == 1) 101 { 102 lv.Update(1, p, x); 103 } 104 else 105 { 106 printf("%lld\n", lv.Search(1, p, x)); 107 } 108 } 109 return 0; 110 }
代码2:递归
1 #include <fstream> 2 #include <iostream> 3 using namespace std; 4 5 #define MAX 100005 6 #define ll long long int 7 8 class SegmentTree 9 { 10 private: 11 int n; 12 struct Node 13 { 14 int left, right, mid; 15 ll maxval; 16 Node (): maxval(0) 17 {} 18 }*tree; 19 public: 20 SegmentTree (int n): n(n) 21 { 22 tree = new Node[n<<2]; 23 } 24 ~SegmentTree () 25 { 26 delete []tree; 27 } 28 void Build (int id, int left, int right); 29 void Update (int id, int subid, int val); 30 ll Search (int id, int left, int right); 31 }; 32 void SegmentTree::Build (int id, int left, int right) //递归 33 { 34 tree[id].left = left; 35 tree[id].right = right; 36 tree[id].mid = (left + right) >> 1; 37 if (tree[id].mid == right) 38 { 39 return; 40 } 41 Build(id << 1, left, tree[id].mid); 42 Build((id << 1)|1, tree[id].mid + 1, right); 43 } 44 void SegmentTree::Update (int id, int subid, int val) 45 { 46 if (tree[id].left == tree[id].right) 47 { 48 tree[id].maxval += val; 49 } 50 else if (tree[id].mid >= subid) 51 { 52 Update(id << 1, subid, val); 53 tree[id].maxval = max(tree[id << 1].maxval, tree[id].maxval); 54 } 55 else if (tree[id].mid < subid) 56 { 57 Update((id << 1)|1, subid, val); 58 tree[id].maxval = max(tree[id].maxval, tree[(id << 1)|1].maxval); 59 } 60 } 61 ll SegmentTree::Search (int id, int left, int right) 62 { 63 if (tree[id].left == left && tree[id].right == right) 64 { 65 return tree[id].maxval; 66 } 67 else if (tree[id].mid >= right) 68 { 69 return Search(id << 1, left, right); 70 } 71 else if (tree[id].mid < left) 72 { 73 return Search((id << 1)|1, left, right); 74 } 75 else 76 { 77 return max(Search(id << 1, left, tree[id].mid), Search((id << 1)|1, tree[id].mid + 1, right)); 78 } 79 } 80 81 int main () 82 { 83 //freopen("D:\\input.in","r",stdin); 84 int n, q, t, p, x; 85 scanf ("%d %d", &n, &q); 86 SegmentTree lv(n); 87 lv.Build(1, 1, n); 88 for (int i = 0; i < q; i++) 89 { 90 scanf ("%d %d %d", &t, &p, &x); 91 if (t == 1) 92 { 93 lv.Update(1, p, x); 94 } 95 else 96 { 97 printf("%lld\n", lv.Search(1, p, x)); 98 } 99 } 100 return 0; 101 }