HDU 1166 - 敌兵布阵

题目链接: 敌兵布阵

思路

区间修改和区间查询,用树状数组快速A了,可能是长时间不写线段树的原因,竟然忘了要开4倍数组,一直TLE。

  • 线段树
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
#include <bits/stdc++.h>
using namespace std;
int seqtree[200001],n,p;
int a[200001];
int read()
{
int x = 0, f = 1;
char ch = getchar();
while(ch < '0' || ch > '9')
{
if(ch == '-')
f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9')
{
x = x * 10 + ch - '0';
ch = getchar();
}
return x * f;
}
void maketree(int node,int begin, int end)
{
if(begin == end)
{
seqtree[node] = read();
return;
}
int mid = (begin + end) >> 1;
maketree(node << 1, begin, mid);
maketree(node << 1|1, mid + 1,end);
seqtree[node] = seqtree[node << 1] + seqtree[node << 1|1];
}
void update(int node,int begin,int end,int pos,int grade)
{
if(pos < begin || pos > end)
return ;
if(begin == end && begin == pos)
{
seqtree[node] += grade;
return ;
}
int mid = (begin + end) >> 1;
update(node << 1,begin, mid, pos,grade);
update(node << 1|1, mid + 1, end, pos, grade);
seqtree[node] = seqtree[node << 1] + seqtree[node << 1|1];
}
int query(int node,int begin,int end,int l,int r)
{
if(l > end || r < begin)
return 0;
else if(l <= begin && r >= end)
return seqtree[node];
int sum = 0;
int mid = (begin + end) >> 1;
sum += query(node << 1,begin,mid,l,r);
sum += query(node << 1|1,mid + 1,end, l,r);
return sum;
}
int main()
{
int t,A,B,caser = 1;
char s[101];
scanf("%d",&t);
while(t--)
{
printf("Case %d:\n",caser++);
memset(seqtree,0,sizeof(seqtree));
scanf("%d",&n);
maketree(1,1,n);
while(scanf("%s",s))
{
if(s[0] == 'E')
break;
else if(s[0] == 'Q')
{
scanf("%d %d",&A,&B);
printf("%d\n",query(1,1,n,A,B));
}
else if(s[0] == 'A')
{
scanf("%d %d",&A,&B);
update(1,1,n,A,B);
}
else if(s[0] == 'S')
{
scanf("%d %d",&A,&B);
update(1,1,n,A,-B);
}
}
}
}

  • 树状数组

    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
    #include <bits/stdc++.h>
    using namespace std;
    int tree[100001],n;
    int lowbit(int x)
    {
    return (x & (-x));
    }
    void update(int x,int k)
    {
    for(int i = x; i <= n; i += lowbit(i))
    {
    tree[i] += k;
    }
    }
    int Query(int x)
    {
    int sum = 0;
    for(int i = x; i > 0 ; i -= lowbit(i))
    {
    sum += tree[i];
    }
    return sum;
    }
    int main()
    {
    int t, num, A, B, caser = 1;
    string s;
    scanf("%d",&t);
    while(t--)
    {
    printf("Case %d:\n",caser++);
    memset(tree,0,sizeof(tree));
    scanf("%d",&n);
    for(int i = 1; i <= n ;++i)
    {
    scanf("%d",&num);
    update(i,num);
    }
    while(cin >> s)
    {
    if(s == "End")
    break;
    if(s[0] == 'Q')
    {
    scanf("%d %d",&A,&B);
    cout << Query(B) - Query(A - 1) << endl;
    }
    else if(s[0] == 'A'){
    scanf("%d %d",&A,&B);
    update(A,B);
    }
    else{
    scanf("%d %d",&A,&B);
    update(A, -B);
    }
    }
    }
    }