hdu 1166 敌兵布阵
2013-08-27 00:14
148 查看
hdu 1166 敌兵布阵
这是一道树状数组的入门题啦.
学习树状数组的时候多拿笔算算就比较好理解为什么算法的查询和修改都是logn的了.
c[i] = a[i - 2^k + 1] + a[i - 2^k + 2] + ... + a[i], 其中k为i的二进制表示最后几位零的个数, 如i=8, 那么1000三个0咯, 那么c[8] = a[1]+a[2]+...+a[8]啦.
还有哦, i的二进制表示末尾0的个数k还表示了c[i]所包含的范围哦.
比如吧, c[5], 5的二进制数是101吧, 最后没有0哦, 那么它只能包含a[5]咯, c[6]呢? 6的二进制是110哦, 所以呢, 它能包含a[5]和a[6]哦
还有呢, i包含的最大的2的幂的因子也能表示i所能包含的个数哦, 如i=5吧, 5没有包含2^x的因子吧, 所以呢, 它只能包含a[5]咯
i=4呢. 它有2^2嘛, 所以它能包含4个, i=6, 它只有2^1, 所以它只能包含a[5]和a[6]咯
所有基数都是没有2的幂的因子吧, 所以基数只能包含一个咯. 即c[1]=a[1], c[3]=a[3]...
这是一道树状数组的入门题啦.
学习树状数组的时候多拿笔算算就比较好理解为什么算法的查询和修改都是logn的了.
c[i] = a[i - 2^k + 1] + a[i - 2^k + 2] + ... + a[i], 其中k为i的二进制表示最后几位零的个数, 如i=8, 那么1000三个0咯, 那么c[8] = a[1]+a[2]+...+a[8]啦.
还有哦, i的二进制表示末尾0的个数k还表示了c[i]所包含的范围哦.
比如吧, c[5], 5的二进制数是101吧, 最后没有0哦, 那么它只能包含a[5]咯, c[6]呢? 6的二进制是110哦, 所以呢, 它能包含a[5]和a[6]哦
还有呢, i包含的最大的2的幂的因子也能表示i所能包含的个数哦, 如i=5吧, 5没有包含2^x的因子吧, 所以呢, 它只能包含a[5]咯
i=4呢. 它有2^2嘛, 所以它能包含4个, i=6, 它只有2^1, 所以它只能包含a[5]和a[6]咯
所有基数都是没有2的幂的因子吧, 所以基数只能包含一个咯. 即c[1]=a[1], c[3]=a[3]...
#include <stdio.h> #include <string.h> #define MAX 50005 int a[MAX]; int c[MAX]; int n; int lowbit(int index) { return index & (-index); } int query(int index) { int result = 0; while (index > 0) { result += c[index]; index -= lowbit(index); } return result; } void add(int index, int delta) { while (index <= n) { c[index] += delta; index += lowbit(index); } } void sub(int index, int delta) { while (index <= n) { c[index] -= delta; index += lowbit(index); } } int main() { int T, t; int i, j; int lb; char q[10]; int x, y; while (scanf("%d", &T) == 1) { t = 0; while (T--) { memset(a, 0, sizeof(a)); memset(c, 0, sizeof(c)); scanf("%d", &n); for (i = 1; i <= n; i++) { scanf("%d", &a[i]); } for (i = 1; i <= n; i++) { lb = lowbit(i); for (j = i - lb + 1; j <= i; j++) { c[i] += a[j]; } } printf("%d", query(5) - query(4)); t++; while (true) { scanf("%s", q); if (!strcmp(q, "End")) { break ; } scanf("%d%d", &x, &y); if (!strcmp(q, "Query")) { // printf("%d\n", query(y) - query(x) + query(x - 1)); printf("%d\n", query(y) - query(x) + a[x]); } else if (!strcmp(q, "Add")) { add(x, y); a[x] += y; } else { sub(x, y); a[x] -= y; } } } } return 0; }
相关文章推荐
- HDU 1166 敌兵布阵 【简单的树状数组||线段树】
- 【线段树I:母题】hdu 1166 敌兵布阵
- HDU1166敌兵布阵-线段树求和
- HDU_1166 敌兵布阵
- [ACM_数据结构] HDU 1166 敌兵布阵 线段树 或 树状数组
- HDU 1166 敌兵布阵(树状数组)
- HDU 1166 敌兵布阵(线段树 单点更新)
- HDU 1166 敌兵布阵 <线段树 单点修改 区间查询>
- HDU 1166 敌兵布阵
- hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵 //线段树单点更新
- HDU1166敌兵布阵 简单线段树
- hdu 1166 敌兵布阵(线段树入门-单点更新)
- hdu 1166 敌兵布阵(树状数组)
- HDU 1166 敌兵布阵 算法学习:线段树
- HDU - 1166 敌兵布阵(新手入门级)
- HDU 1166 敌兵布阵(线段树)
- HDU 1166 敌兵布阵
- HDU1166 敌兵布阵 【线段树】
- HDU 1166 敌兵布阵(线段树基础)