HDU 1166 —— 敌兵布阵 【树状数组 or 线段树】
2016-05-18 21:38
435 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1166
需求:
1.点修改
2.区间求和
标准的BIT(二叉索引树,又名树状数组)问题,当然也可以用最基础的仅支持“点修改”的线段树来解决!
需求:
1.点修改
2.区间求和
标准的BIT(二叉索引树,又名树状数组)问题,当然也可以用最基础的仅支持“点修改”的线段树来解决!
1.线段树版本:
#include <cstdio> #include <iostream> #define INF 0x3f3f3f3f using namespace std; const int MAXN = 65536 + 5; // 65536 是最小的大于等于50000的2^k, 这里如果写成50000 + 5 可是要超时的! int sumv[MAXN*2-1]; int n, N; int ql, qr; int query(int o, int l, int r) { if(qr < l || r < ql) return 0; if(ql <= l && r <= qr) return sumv[o]; int m = (l + r) >> 1, ret = 0; ret += query((o << 1) + 1, l, m); ret += query((o << 1) + 2, m + 1, r); return ret; } void update(int k, int v) { k += N-1; sumv[k] = v; while(k>0) { k = (k-1) >> 1; sumv[k] = sumv[(k << 1) + 1] + sumv[(k << 1) + 2]; } } char s[20]; int main () { int T, p, q, v; scanf("%d", &T); for(int kase = 1; kase <= T; kase++) { scanf("%d", &n); N = 1; while(N < n) N <<= 1; // 找到最小的大于等于n的2^k,因为叶子节点至少要放得下n个数字 int tot = (1<<N)-1; for(int i=0; i<tot; i++) sumv[i] = 0; // 初始化 // 构建线段树 O(nlgn) // for(int i=0; i<n; i++) { // scanf("%d", &v); // update(i, v); // } // 构建线段树 O(n) for(int i=0; i<n; i++) { scanf("%d", &sumv[N-1+i]); } for(int i=N-2; i>=0; i--) { sumv[i] = sumv[(i << 1) + 1] + sumv[(i << 1) + 2]; } printf("Case %d:\n", kase); while(scanf("%s", s) != EOF && s[0] != 'E') { scanf("%d%d", &p, &q); if(s[0] == 'A') { update(p-1, sumv[p-1+N-1] + q); } else if(s[0] == 'S') { update(p-1, sumv[p-1+N-1] - q); } else { ql = p-1; qr = q-1; printf("%d\n", query(0, 0, N-1)); } } } return 0; }
2.树状数组(BIT)版本:
#include <cstdio> #include <iostream> #include <cstring> #include <string> #define INF 0x3f3f3f3f using namespace std; const int MAXN = 50000 + 5; int C[MAXN]; char s[20]; int n; int query(int x) { int ret = 0; while(x) { re a923 t += C[x]; x -= x&(-x); } return ret; } void add(int k, int d) { while(k <= n) { C[k] += d; k += k&(-k); } } int main () { int T, p, q, x; scanf("%d", &T); for(int kase = 1; kase <= T; kase++) { scanf("%d", &n); for(int i=1; i<=n; i++) { scanf("%d", &x); add(i, x); } printf("Case %d:\n", kase); while(scanf("%s", s) != EOF && s[0] != 'E') { scanf("%d%d", &p, &q); if(s[0] == 'A') { add(p, q); } else if(s[0] == 'S') { add(p, -q); } else { printf("%d\n", query(q) - query(p-1)); } } memset(C, 0, sizeof(C)); } return 0; }
相关文章推荐
- hiho 1290 —— Demo Day 【DP】
- hiho 1033 —— 交错和 【数位DP】
- POJ - 3286 - How many 0s? 【数位DP】
- ZOJ - 3609 —— Modular Inverse 【乘法逆,扩展欧几里得】
- POJ 1061 —— 青蛙的约会
- 利用Arcpy发布地图服务,制作切片
- HDU 4507 —— 吉哥系列故事――恨7不成妻
- CodeForces 55D - Beautiful numbers
- ORA-01122: database file 4 failed verification check
- 杭电1260
- 进程间通信之FIFO
- C++primer
- LINUX——sort命令
- SPOJ BALNUM - Balanced Numbers
- HDU 3709 —— Balanced Number
- poj3277 City Horizon(矩形面积并)
- HDU 3652 —— B-number
- POJ 3252 —— Round Numbers
- HDU 2089 —— 不要62
- HDU 3555 —— Bomb