Contents
  1. 1. hdu 1166
  2. 2. 分析:

hdu 1166

分析:

1 题目给定n个兵营的人数,现在有三种操作
(1)Add i j,i和j为正整数,表示第i个营地增加j个人(j不超过30)
(2)Sub i j ,i和j为正整数,表示第i个营地减少j个人(j不超过30);
(3)Query i j ,i和j为正整数,i<=j,表示询问第i到第j个营地的总人数;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

#define Lson(x) (x<<1) //左移相当于乘2; 2*n
#define Rson(x) (Lson(x)|1) //相当于2*n + 1
#define Mid(x,y) ((x+y)>>1) //右移相当于除2,相当于n / 2
#define Sum(x,y) (x+y)

const int N = 10;
const int MAXN = 50010;

int n;
int num[MAXN];
struct Node{
int left;
int right;
int sum;
};
Node node[4*MAXN]; //n个数,则线段树占4倍n的内存

void push_up(int pos){
node[pos].sum = Sum(node[Lson(pos)].sum,node[Rson(pos)].sum);
}

void init(int left , int right , int pos){
node[pos].left = left;
node[pos].right = right;

if(left == right){ //叶子节点
node[pos].sum = num[left];
return;
}

int x = Mid(left , right);

init(left , x , Lson(pos)); //向左节点去
init(x+1 , right , Rson(pos)); //向右节点去
push_up(pos); //回溯的时候对本节点的sum赋值(左孩子的sum+右孩子的sum)
}

void update(int index , int val , int pos){
if(node[pos].left == node[pos].right){ //更新叶子节点
node[pos].sum += val;
return;
}

int x = Mid(node[pos].left , node[pos].right);

if(index <= x)
update(index , val , Lson(pos)); //更新左孩子
else
update(index , val , Rson(pos)); //更新右孩子
push_up(pos); //回溯的时候更新本节点
}

int query(int left , int right , int pos){
if(node[pos].left == left && node[pos].right == right)
return node[pos].sum;

int x = Mid(node[pos].left , node[pos].right);

if(right <= x) //在左孩子的区间里
return query(left , right , Lson(pos));
else if(left > x) //在右孩子的区间里
return query(left , right , Rson(pos));
else //如果有部分在左孩子的区间和右孩子的区间里,就将其分为两个区间
return query(left , x , Lson(pos))+query(x+1 , right , Rson(pos));
}


void input(){
char str[N];
scanf("%d" , &n);
for(int i = 1 ; i <= n ; i++)
scanf("%d" , &num[i]);
init(1 , n , 1); //初始化区间[1, n],从pos=1开始
getchar();
int x , y;
while(scanf("%s" , str) && str[0] != 'E'){
scanf("%d%d%*c" , &x , &y);
if(str[0] == 'Q')
printf("%d\n" , query(x , y , 1));
else if(str[0] == 'A')
update(x , y , 1);
else
update(x , -y , 1);
}
}

int main(){
int Case;
int cas = 1;
scanf("%d" , &Case);
while(Case--){
printf("Case %d:\n" , cas++);
input();
}
return 0;
}
Contents
  1. 1. hdu 1166
  2. 2. 分析: