HDU 1166 敌兵布阵(第一个线段树)
这个题,用完树状数组,再用线段树水过。线段树,却是感觉比树状数组的功能强多了。只要把线段树的思想理解,然后把实现过程,递归过程了解,单点更新就没问题了。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 50001
struct node
{
int l;
int r;
int v;
}tree[4*N];
void build(int l,int r,int rt)
{
int m;
tree[rt].l = l;
tree[rt].r = r;
if(l == r)
{
scanf("%d",&tree[rt].v);
return;
}
m = (l+r)>>1;
build(l,m,rt<<1);
build(m+1,r,rt<<1|1);
tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v;
}
void update(int pos,int sc,int rt)
{
int m;
if(tree[rt].l == tree[rt].r)
{
tree[rt].v += sc;
return ;
}
m = (tree[rt].l + tree[rt].r) >> 1;
if(pos <= m)
update(pos,sc,rt<<1);
else
update(pos,sc,rt<<1|1);
tree[rt].v = tree[rt<<1].v + tree[rt<<1|1].v;
}
int query(int L,int R,int rt)
{
int m;
if(tree[rt].l == L&&tree[rt].r == R)
{
return tree[rt].v;
}
m = (tree[rt].l + tree[rt].r) >> 1;
if(L > m)
{
return query(L,R,rt<<1|1);
}
else if(R <= m)
{
return query(L,R,rt<<1);
}
else
{
return query(L,m,rt<<1)+query(m+1,R,rt<<1|1);
}
}
int main()
{
int t,num = 0,x,y,n;
char str[100];
scanf("%d",&t);
while(t--)
{
num ++;
memset(tree,0,sizeof(tree));
scanf("%d",&n);
build(1,n,1);
scanf("%s",str);
printf("Case %d:\n",num);
while(strcmp(str,"End") != 0)
{
scanf("%d%d%*c",&x,&y);
if(strcmp(str,"Query") == 0)
printf("%d\n",query(x,y,1));
else if(strcmp(str,"Add") == 0)
update(x,y,1);
else if(strcmp(str,"Sub") == 0)
update(x,-y,1);
scanf("%s",str);
}
}
return 0;
}

浙公网安备 33010602011771号