线段树(单点更新)/树状数组 HDOJ 1166 敌兵布阵

时间:2022-04-17 05:14:31

题目传送门

 /*
线段树基本功能:区间值的和,修改某个值
*/
#include <cstdio>
#include <cstring>
#define lson l, m, rt << 1
#define rson m+1, r, rt << 1|1 const int MAX_N = + ;
int sum[MAX_N<<]; void pushup(int rt) //杭电大牛:notOnlySuccess 版本
{
sum[rt] = sum[rt<<] + sum[rt<<|];
} void build(int l, int r, int rt)
{
if (l == r)
{
scanf ("%d", &sum[rt]);
return ;
}
int m = (l + r) >> ;
build (lson);
build (rson);
pushup (rt);
} void update(int p, int add, int l, int r, int rt)
{
if (l == r)
{
sum[rt] += add;
return ;
}
int m = (l + r) >> ;
if (p <= m) update (p, add, lson);
else update (p, add, rson);
pushup (rt);
} int query(int ql, int qr, int l, int r, int rt)
{
if (ql <= l && r <= qr)
{
return sum[rt];
}
int m = (l + r) >> ;
int ans = ;
if (ql <= m) ans += query (ql, qr, lson);
if (qr > m) ans += query (ql, qr, rson); return ans;
} int main(void) //HDOJ 1166 敌兵布阵
{
//freopen ("inA.txt", "r", stdin);
int t, n, cas, ans;
int b, c;
char s[]; while (~scanf ("%d", &t))
{
cas = ;
while (t--)
{
scanf ("%d", &n);
build (, n, );
printf ("Case %d:\n", ++cas);
while (~scanf ("%s", &s))
{
if (strcmp (s, "End") == ) break;
scanf ("%d%d", &b, &c);
if (strcmp (s, "Query") == )
{
ans = query (b, c, , n, );
printf ("%d\n", ans);
}
else if (strcmp (s, "Add") == )
{
update (b, c, , n, );
}
else if (strcmp (s, "Sub") == )
{
update (b, -c, , n, );
}
}
}
} return ;
}
 /*
树状数组
*/
#include <cstdio>
#include <cstring> const int MAX_N = + ;
int a[MAX_N];
int n, num; int lowbit(int t) //求 2^k
{
//return t & (t ^ (t - 1));
return t & (-t);
} void plus(int num, int x) //第i个增加num个人
{
while (x <= n)
{
a[x] += num;
x += lowbit (x);
}
} int sum(int x) //求前x项的和
{
int sum = ;
while (x > )
{
sum += a[x];
x -= lowbit(x);
}
return sum;
} int main(void)
{
//freopen ("inA.txt", "r", stdin); int t;
char op[]; scanf ("%d", &t);
int k = t; while (k--)
{
memset (a, , sizeof (a));
scanf ("%d", &n);
for (int i=; i<=n; ++i)
{
scanf ("%d", &num);
plus (num, i);
}
int r = ;
while (scanf ("%s", &op), op[] != 'E')
{
int a, b;
scanf ("%d%d", &a, &b);
switch (op[])
{
case 'A':
plus (b, a);
break;
case 'S':
plus (-b, a);
break;
case 'Q':
if (r)
printf ("Case %d:\n", t - k);
r = ;
printf ("%d\n", sum (b) - sum (a-));
break;
}
}
} return ;
}

树状数组