您的位置:首页 > 其它

HDU 1166 敌兵布阵(线段树)

2015-07-22 21:27 405 查看
题目连接:Click here

思路:简单的单点更新,区间查询。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;

int ans[250005];

void build(int left, int right, int f)
{//建立线段树
int mid;
if(left == right)   //如果左边等于右边,证明到达叶子节点
scanf("%d", &ans[f]);
else
{
mid = (left + right) / 2;
build(left, mid, f * 2);  //f是节点的信息,f*2是其左子树节点的下标
build(mid + 1, right, f * 2 + 1);
ans[f] = ans[f*2] + ans[f*2+1];
}
}

void update(int place, int add, int left, int right, int f)
{//更新线段树信息
int mid;
ans[f] += add;
if(left == right)return;
mid = (left + right) / 2;
if(place <= mid)
update(place, add, left, mid, f * 2);
else
update(place, add, mid + 1, right, f * 2 + 1);
}

int que(int ql, int qr, int left, int right, int f)
{//查询区间ql-qr的值
int ans2, mid;
ans2 = 0;
if(ql <= left && right <= qr) return ans[f];
mid = (left + right) / 2;
if(qr > mid) ans2 += que(ql, qr, mid + 1, right, f * 2 + 1);
if(ql <= mid) ans2 += que(ql, qr, left, mid, f * 2);
return ans2;
}

int main()
{
int t, n, a, b;
char ord[20];
scanf("%d", &t);
for(int k = 1; k <= t; k++)
{
printf("Case %d:\n", k);
scanf("%d", &n);
build(1, n, 1);
while(scanf("%s", ord) != EOF)
{
if(ord[0] == 'E')break;
if(ord[0] == 'Q')

4000
{
scanf("%d%d", &a, &b);
printf("%d\n", que(a, b, 1, n, 1));
}
if(ord[0] == 'A')
{
scanf("%d%d", &a, &b);
update(a, b, 1, n, 1);
}
if(ord[0] == 'S')
{
scanf("%d%d", &a, &b);
update(a, -b, 1, n, 1);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: