标签:
题目链接:http://poj.org/problem?id=3468
线段树区间更新查询的样题,注意数据范围。连要更新的数据也必须是long long。
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cstring> 4 #include <algorithm> 5 #include <iostream> 6 #include <cmath> 7 #include <queue> 8 #include <map> 9 #include <stack> 10 #include <list> 11 #include <vector> 12 13 using namespace std; 14 15 const int maxn = 2000010; 16 17 typedef long long LL; 18 typedef struct Node { 19 LL value; 20 LL mark; 21 LL left, right, mid; 22 }Node; 23 24 Node node[maxn<<1]; 25 LL father[maxn]; 26 LL ans; 27 LL score[maxn]; 28 29 inline LL max(LL a, LL b) { 30 return a > b ? a : b; 31 } 32 33 //建树 34 void build(LL left, LL right, LL i) { 35 node[i].left = left; 36 node[i].right = right; 37 node[i].mid = (left + right) >> 1; 38 // node[i].value = 0; 39 node[i].mark = 0; 40 if(left == right) { 41 // father[left] = i; 42 node[i].value = score[left]; 43 return ; 44 } 45 build(node[i].mid+1, right, (i<<1)+1); 46 build(left, node[i].mid, i<<1); 47 node[i].value = node[i*2].value + node[i*2+1].value; 48 } 49 50 //点更新 51 void pointupdate(LL i, LL v) { 52 if(i == 1) { //根节点 53 return ; 54 } 55 LL fa = i / 2; 56 LL a = node[2*fa].value; //左儿子 57 LL b = node[2*fa+1].value; //右儿子 58 node[fa].value = max(a, b); // 59 pointupdate(fa, v); 60 } 61 62 //点查询 63 void pointquery(LL left, LL right, LL i) { 64 if(node[i].left == left && node[i].right == right){ 65 ans = max(ans, node[i].value); 66 return ; 67 } 68 //left 69 if(left <= node[2*i].right) { 70 if(right <= node[2*i].right) { 71 pointquery(left, right, i<<1); 72 } 73 else { 74 pointquery(left, node[2*i].right, i<<1); 75 } 76 } 77 //right 78 if(right >= node[2*i+1].left) { 79 if(left >= node[2*i+1].left) { 80 pointquery(left, right, (i<<1)+1); 81 } 82 else { 83 pointquery(node[2*i+1].left, right, (i<<1)+1); 84 } 85 } 86 } 87 88 //区间更新 89 void intervalupdate(LL left, LL right, LL v, LL i) { 90 if(node[i].left == left && node[i].right == right) { 91 node[i].mark += v; 92 return ; 93 } 94 node[i].value += v * (right - left + 1); 95 if(node[i].mid < left) { 96 intervalupdate(left, right, v, (i<<1)+1); 97 } 98 else if(node[i].mid >= right) { 99 intervalupdate(left, right, v, i<<1); 100 } 101 else { 102 intervalupdate(left, node[i].mid, v, i<<1); 103 intervalupdate(node[i].mid+1, right, v, (i<<1)+1); 104 } 105 } 106 107 //区间查询 108 LL intervalquery(LL left, LL right, LL i) { 109 if(node[i].left == left && node[i].right == right) { 110 return node[i].value + node[i].mark * (right - left + 1); 111 } 112 if(node[i].mark != 0) { 113 node[i*2].mark += node[i].mark; 114 node[i*2+1].mark += node[i].mark; 115 node[i].value += (node[i].right - node[i].left + 1) * node[i].mark; 116 node[i].mark = 0; 117 } 118 if(node[i].mid >= right) { 119 return intervalquery(left, right, i<<1); 120 } 121 else if(node[i].mid < left) { 122 return intervalquery(left, right, (i<<1)+1); 123 } 124 else { 125 return intervalquery(left, node[i].mid, i<<1) + intervalquery(node[i].mid+1, right, (i<<1)+1); 126 } 127 } 128 129 int main() { 130 // freopen("in", "r", stdin); 131 LL n, m; 132 char cmd[2]; 133 LL a, b, tmp; 134 while(~scanf("%I64d %I64d", &n, &m)) { 135 for(LL i = 1; i <= n; i++) { 136 scanf("%I64d", &score[i]); 137 } 138 build(0, n, 1); 139 while(m--) { 140 scanf("%s", cmd); 141 if(cmd[0] == ‘Q‘) { 142 scanf("%I64d %I64d", &a, &b); 143 printf("%I64d\n", intervalquery(a, b, 1)); 144 } 145 else if(cmd[0] == ‘C‘) { 146 scanf("%I64d %I64d %I64d", &a, &b, &tmp); 147 // node[father[a]].value = b; 148 intervalupdate(a, b, tmp, 1); 149 } 150 } 151 } 152 return 0; 153 }
[POJ3468]A Simple Problem with Integers
标签:
原文地址:http://www.cnblogs.com/vincentX/p/4771834.html