题目链接:hdu 1166 敌兵布阵
题目大意:略。
解题思路:
方法1:树状数组的水题。这篇题解很好,适合初学树状数组的人。题解连接
#include <stdio.h> #include <string.h> const int N = 50005; const int M = 105; int n, v[N]; void add(int x, int val) { while (x <= n) { v[x] += val; x += (x & (-x)); } } void init() { memset(v, 0, sizeof(v)); int a; scanf("%d", &n); for (int i = 1; i <= n; i++) { scanf("%d", &a); add(i, a); } } int sum(int x) { int ans = 0; while (x > 0) { ans += v[x]; x -= (x & (-x)); } return ans; } void solve() { int x, y; char order[M]; while (scanf("%s", order) == 1 && strcmp(order, "End") ) { scanf("%d%d", &x, &y); if (order[0] == 'A') add(x, y); else if (order[0] == 'S') add(x, -y); else printf("%d\n", sum(y) - sum(x-1)); } } int main() { int cas; scanf("%d", &cas); for (int i = 1; i <= cas; i++) { printf("Case %d:\n", i); init(); solve(); } return 0; }
方法二:今天看了一下线段树,这题也可以用线段树做,更新点查询区间。
#include <stdio.h> #include <string.h> const int N = 50005; struct node { int l, r, v; }s[N*3]; void build(int l, int r, int f) { if (l != r) { int mid = (l + r) / 2; build(l, mid, f*2); build(mid+1, r, f*2+1); } s[f].l = l; s[f].r = r; s[f].v = 0; } void insert(int l, int r, int val, int f) { if (s[f].l != s[f].r) { int mid = (s[f].l + s[f].r) / 2; if (l <= mid && r > mid) { insert(l, mid, val, f*2); insert(mid+1, r, val, f*2+1); } else if (l <= mid && r <= mid) insert(l, r, val, f*2); else insert(l, r, val, f*2+1); } s[f].v += val; } int query(int l, int r, int f) { if (l == s[f].l && r == s[f].r) return s[f].v; int mid = (s[f].l + s[f].r) / 2; if (l <= mid && r > mid) return query(l, mid, f*2) + query(mid+1, r, f*2+1); else if (l <= mid && r <= mid) return query(l, r, f*2); else return query(l, r, f*2+1); } void init () { int n, a; scanf("%d", &n); build(1, n, 1); for (int i = 1; i <= n; i++) { scanf("%d", &a); insert(i, i, a, 1); } } void solve () { int a, b; char o[20]; while (scanf("%s", o), strcmp(o, "End")) { scanf("%d%d", &a, &b); if (o[0] == 'A') insert(a, a, b, 1); else if (o[0] == 'S') insert(a, a, -b, 1); else printf("%d\n", query(a, b, 1)); } } int main () { int cas; scanf("%d", &cas); for (int i = 1; i <= cas; i++) { printf("Case %d:\n", i); init(); solve(); } return 0; }