HDU - 1166 敌兵布阵
2017-08-26 17:53
302 查看
题目链接 :
hdu-1166题目大意:
给n个数,有询问有修改,每次询问某个区间[l,r]的和,每次修改某个位置的值。数据范围 :
n≤50000 1≤ai≤50解题思路:
线段树模板,单点修改,区间求和。//线段树--单点修改,区间求和 #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <set> #include <map> #include <queue> using namespace std; typedef long long LL; const int inf = 1 << 30; const LL INF = 1LL << 60; const int MaxN = 5e4; int T, cas; int n; int a[MaxN + 5]; struct Segtree { int l, r; int sum; }tree[4 * MaxN + 5]; void Build(int root, int l, int r) { tree[root].l = l, tree[root].r = r; if(l == r) { tree[root].sum = a[l]; return; } int mid = (l + r) >> 1; Build(root << 1, l, mid); //递归建树 Build(root << 1 | 1, mid + 1, r); tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum; } void update(int root, int pos, int val) //更新操作 { if(tree[root].l == tree[root].r) { tree[root].sum = val; return ; } int mid = (tree[root].l + tree[root].r) >> 1; if(pos <= mid) update(root << 1, pos, val); //更新左儿子 else update(root << 1 | 1, pos, val); //更新右儿子 tree[root].sum = tree[root << 1].sum + tree[root << 1 | 1].sum; //更新完毕后更新区间和 } int query(int root, int L, int R) //查询 { if(L <= tree[root].l && R >= tree[root].r) return tree[root].sum; int res = 0; int mid = (tree[root].l + tree[root].r) >> 1; if(mid >= L) res += query(root << 1, L, R); if(mid < R) res += query(root << 1 | 1, L, R); return res; } int main() { scanf("%d", &T); cas = 0; while(T--) { cas++; scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); } printf("Case %d:\n", cas); Build(1, 1, n); char s[8]; while(scanf("%s", s) ) { if(s[0] == 'E') break; else if(s[0] == 'A') { int p, val; scanf("%d %d", &p, &val); a[p] += val; update(1, p, a[p]); //单点修改 } else if(s[0] == 'S') { int p, val; scanf("%d %d", &p, &val); a[p] -= val; update(1, p, a[p]); //单点修改 } else if(s[0] == 'Q') { int l, r; scanf("%d %d", &l, &r); int ans = query(1, l, r); //询问区间[l, r]的和 printf("%d\n", ans); } } memset(tree, 0, sizeof(tree)); } return 0; }
也可以用树状数组做:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const int MaxN = 1e4; int T, n; int t; int a[5 * MaxN + 5]; int c[5 * MaxN + 5]; char s[10]; int lowbit(int x) { return x & (-x); } void add(int x, int val) { while(x <= n) { c[x] += val; x += lowbit(x); } } int query(int end) { int sum = 0; while(end > 0) { sum += c[end]; end = end - lowbit(end); } return sum; } int main() { t = 0; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); add(i, a[i]); } printf("Case %d:\n", ++t); while(scanf("%s", s)) { if(s[0] == 'E') break; else if(s[0] == 'A') { getchar(); int x, val; scanf("%d %d", &x, &val); add(x, val); } else if(s[0] == 'Q') { getchar(); int l, r; scanf("%d %d", &l, &r); printf("%d\n", query(r) - query(l - 1)); } else if(s[0] == 'S') { getchar(); int x, val; scanf("%d %d", &x, &val); add(x, -val); } } memset(a, 0, sizeof(a)); memset(c, 0, sizeof(c)); } return 0; }
相关文章推荐
- HDU 1166 敌兵布阵(线段树,树状数组)
- HDU 1166 敌兵布阵 我的第一棵树,线段树,树状数组。
- HDU 1166 敌兵布阵(线段树更新单节点模板):
- HDU 1166 敌兵布阵 (线段树单点更新 区间查询)
- HDU - 1166 - 敌兵布阵 (树状数组 or 线段树)
- hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵(线段树,区间求和)
- hdu 1166 敌兵布阵 朴素线段树
- HDU 1166 敌兵布阵
- HDU-1166 线段树-敌兵布阵
- hdu-1166-敌兵布阵-线段树-单点更新,区域查询
- HDU 1166 敌兵布阵 树状数组||线段树
- 敌兵布阵 HDU - 1166
- HDU-1166 敌兵布阵 树状数组
- 线段树系列(一) HDU 1166 敌兵布阵
- HDU—1166—敌兵布阵—【数据结构】【线段树】【单点更新】
- HDU 1166 敌兵布阵
- hdu 1166 敌兵布阵 (线段树)
- HDU 1166 敌兵布阵
- HDU 1166 敌兵布阵(线段树求sum)