通过参考大神们的文章,准备开始要一个一个把上面的题目做一遍了,有很多都是原来做过的,现在也再次做一遍方便以后查阅
HDU 1166 敌兵布阵
单点增减,区间和查询
线段树:
#include <cstdio> #include <cstring> using namespace std; const int N = 50005; #define ls o<<1 #define rs o<<1|1 int a[N]; char s[10]; struct Tree{ int l , r , sum; }tree[N<<2]; void build(int o , int l , int r) { int m = (l + r) >> 1; tree[o].l = l , tree[o].r = r; if(l == r){ tree[o].sum = a[l]; return ; } build(ls , l , m); build(rs , m+1 , r); tree[o].sum = tree[ls].sum + tree[rs].sum; } void update(int o , int i , int j , int op) { if(tree[o].l == tree[o].r && tree[o].r == i){ if(op == 1) tree[o].sum += j; if(op == 2) tree[o].sum -= j; return ; } int m = (tree[o].l + tree[o].r) >> 1; if(m >= i) update(ls , i , j , op); if(m+1 <= i) update(rs , i , j , op); tree[o].sum = tree[ls].sum + tree[rs].sum; } int query(int o , int s , int t) { if(tree[o].l >= s && tree[o].r <= t) return tree[o].sum; int m = (tree[o].l + tree[o].r) >> 1; int ans = 0; if(m >= s) ans += query(ls , s , t); if(m+1 <= t) ans += query(rs , s , t); return ans; } int main() { // freopen("a.in" , "r" , stdin); int T , cas = 0; scanf("%d" , &T); while(T--){ int n , aa , bb; scanf("%d" , &n); for(int i = 1 ; i<=n ; i++) scanf("%d" , &a[i]); build(1 , 1 , n); printf("Case %d:\n" , ++cas); while(scanf("%s" , s)) { if(s[0] == 'E') break; scanf("%d%d" , &aa , &bb); if(s[0] == 'A') update(1 , aa , bb , 1); else if(s[0] == 'S') update(1 , aa , bb , 2); else printf("%d\n" , query(1 , aa , bb)); } } return 0; }