您的位置:首页 > 其它

hdu(1166))敌兵布阵

2013-07-29 16:11 218 查看
第一道:线段数题,虽然用时很长,但很值得。。

#include<stdio.h>

#include<string.h>

#define N 55000

struct point

{

int x,y;//x,y分别表示区间的左右边界

int sum;//表示当前区间的和

}a[N*3];

void tree(int t,int x,int y)//建树

{

a[t].x=x;

a[t].y=y;

a[t].sum=0;

if(x==y)//如果x==y,表示更新到了叶节点((必须放在a[t]赋值下面))不然无法运行))

return ;

int temp=2*t;

int mid=(x+y)/2;

tree(temp,x,mid);//对左儿子建树

tree(temp+1,mid+1,y);//对右儿子建树

}

void IN(int t,int x,int y)//使第x个营地的值加上y

{

if(a[t].x==a[t].y)//更新到了叶节点

{

a[t].sum+=y;

return ;

}

int temp=2*t;

int mid=(a[t].x+a[t].y)/2;

if(x<=mid)

IN(temp,x,y);//x在左儿子中,将更新传递给左儿子

else

IN(temp+1,x,y);//x在右儿子中,将更新传递给右儿子

a[t].sum=a[temp].sum+a[temp+1].sum;//更新节点的和

}

int find(int t,int x,int y)//查找区间[x,y]的和

{

if(a[t].x==x&&a[t].y==y)

{

return a[t].sum;

}

int temp=2*t;

int mid=(a[t].x+a[t].y)/2;

if(y<=mid)

return find(temp,x,y);

else if(x>mid)

return find(temp+1,x,y);

else

return find(temp,x,mid)+find(temp+1,mid+1,y);

}

int main()

{

int m,n,i,k,h,t,s=1;

char b[100];

scanf("%d",&t);

while(t--)

{

scanf("%d",&m);

tree(1,1,m);

for(i=1;i<=m;i++)

{

scanf("%d",&n);

IN(1,i,n);//为了方便理解,这里的值边输入边插入。也可以在所有的值输入后,在建树的时候直接给树赋值

}

printf("Case %d:\n",s++);

while(scanf("%s",b),strcmp(b,"End"))

{

scanf("%d%d",&k,&h);

if(b[0]=='A')

{

IN(1,k,h);

}

else if(b[0]=='S')

{

IN(1,k,-h);

}

else

{

printf("%d\n",find(1,k,h));

}

}

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: