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;
}
#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;
}
相关文章推荐
- HDU 1166 敌兵布阵 【简单的树状数组||线段树】
- 【线段树I:母题】hdu 1166 敌兵布阵
- HDU1166敌兵布阵-线段树求和
- HDU-1166-敌兵布阵【树状数组讲解笔记】
- HDU_1166 敌兵布阵
- [ACM_数据结构] HDU 1166 敌兵布阵 线段树 或 树状数组
- 【树状数组 单点修改,区间求值】hdu 1166 敌兵布阵
- HDU 1166 敌兵布阵(树状数组)
- HDU 1166 敌兵布阵(线段树 单点更新)
- HDU 1166 敌兵布阵 <线段树 单点修改 区间查询>
- HDU 1166 敌兵布阵 //线段树单点更新
- HDU1166敌兵布阵 简单线段树
- hdu 1166 敌兵布阵(线段树入门-单点更新)
- HDU - 1166 敌兵布阵(初学线段树)
- hdu 1166 敌兵布阵(树状数组)
- HDU 1166 敌兵布阵 算法学习:线段树
- HDU 1166 敌兵布阵(线段树)
- HDU 1166 敌兵布阵
- HDU1166 敌兵布阵 【线段树】
- hdu 1166 敌兵布阵