hdu1166简单线段树
2013-08-18 11:24
369 查看
题意是初始化炮兵人数,然后对其进行一系列修改,最后查询区间人数和
用一般数组做会超时,改用线段树
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int num[50050];
class tree
{public:
int l,r,data; //data存每棵树区间内的人数
}tree[150050];
void insert(int n,int l,int r) //n表示第n个数,从1开始不停地初始化树
{tree
.l=l;
//初始化每棵树代表的左右区间
tree
.r=r;
if(l==r)
tree
.data=num[l]; //num数组存各个兵营的人数
else
{
int mid=(l+r)>>1; //递归继续初始化左右子树
insert(2*n,l,mid);
insert(2*n+1,mid+1,r);
tree
.data=tree[2*n].data+tree[2*n+1].data;
}
}
void modify(int n,int x,int temp)
{if(tree
.l==tree
.r) //修改时,从第一棵树传进来往下搜,然后从下往上维护data
{
tree
.data+=temp;
return ;
}
int mid;
mid=(tree
.l+tree
.r)/2;
if(x<=mid) //x表示第几个兵营,因此用X来和mid做比较从而选择在左子树还是右子树
modify(n*2,x,temp);
else
modify(n*2+1,x,temp);
tree
.data+=temp;
}
int query(int n,int a,int b)
{if(tree
.l==a&&tree
.r==b)//查询同修改类似,先自上而下,然后从下往上返回data值
return tree
.data;
else
{
int mid=(tree
.l+tree
.r)/2; //选择所查询区间在左子树还是右子树,或者是由左右子树部分区间之和
if(a>mid)
return query(n*2+1,a,b);
else
{
if(b<=mid)
return query(n*2,a,b);
else
return query(n*2,a,mid)+query(n*2+1,mid+1,b);
}
}
}
int main()
{int t,key=1;
//freopen("E:\\in.txt","r",stdin);
scanf("%d",&t);
while(t--)
{printf("Case %d:\n",key++);
memset(num,0,sizeof(num));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
insert(1,1,n);
//char str[6];
string str;
int a,b;
while(cin>>str)
{if(str=="End")
break;
scanf("%d%d",&a,&b);
if(str=="Add")
{
modify(1,a,b);
}
if(str=="Sub")
{
modify(1,a,-1*b);
}
if(str=="Query")
{
printf("%d\n",query(1,a,b));
}
}
}
return 0;
}
用一般数组做会超时,改用线段树
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int num[50050];
class tree
{public:
int l,r,data; //data存每棵树区间内的人数
}tree[150050];
void insert(int n,int l,int r) //n表示第n个数,从1开始不停地初始化树
{tree
.l=l;
//初始化每棵树代表的左右区间
tree
.r=r;
if(l==r)
tree
.data=num[l]; //num数组存各个兵营的人数
else
{
int mid=(l+r)>>1; //递归继续初始化左右子树
insert(2*n,l,mid);
insert(2*n+1,mid+1,r);
tree
.data=tree[2*n].data+tree[2*n+1].data;
}
}
void modify(int n,int x,int temp)
{if(tree
.l==tree
.r) //修改时,从第一棵树传进来往下搜,然后从下往上维护data
{
tree
.data+=temp;
return ;
}
int mid;
mid=(tree
.l+tree
.r)/2;
if(x<=mid) //x表示第几个兵营,因此用X来和mid做比较从而选择在左子树还是右子树
modify(n*2,x,temp);
else
modify(n*2+1,x,temp);
tree
.data+=temp;
}
int query(int n,int a,int b)
{if(tree
.l==a&&tree
.r==b)//查询同修改类似,先自上而下,然后从下往上返回data值
return tree
.data;
else
{
int mid=(tree
.l+tree
.r)/2; //选择所查询区间在左子树还是右子树,或者是由左右子树部分区间之和
if(a>mid)
return query(n*2+1,a,b);
else
{
if(b<=mid)
return query(n*2,a,b);
else
return query(n*2,a,mid)+query(n*2+1,mid+1,b);
}
}
}
int main()
{int t,key=1;
//freopen("E:\\in.txt","r",stdin);
scanf("%d",&t);
while(t--)
{printf("Case %d:\n",key++);
memset(num,0,sizeof(num));
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&num[i]);
insert(1,1,n);
//char str[6];
string str;
int a,b;
while(cin>>str)
{if(str=="End")
break;
scanf("%d%d",&a,&b);
if(str=="Add")
{
modify(1,a,b);
}
if(str=="Sub")
{
modify(1,a,-1*b);
}
if(str=="Query")
{
printf("%d\n",query(1,a,b));
}
}
}
return 0;
}
相关文章推荐
- hdu1166(简单线段树应用,求区间和)
- hdu1166 简单线段树
- 【Codeforces 768 B Code For 1】+ 简单线段树
- hdu1166(线段树)
- 简单线段树模板
- 简单的线段树
- hdu1166(线段树模版,区间求和)
- hdu1166(线段树单点更新&区间求和模板)
- 【hdu1166】敌兵布阵——线段树水题
- hdu1166依旧是大山跑线段树题
- 杭电 线段树 (个人整理(基础入门版))(多题练习.)(简单风格)
- HDU 1541 线段树简单更新
- URAL-1987 Nested Segments 线段树简单区间覆盖
- Just a Hook(HDU1698 线段树的简单应用)
- Codeforces 609F Frogs and mosquitoes 二分+简单离散化线段树+Multimap
- 线段树的简单应用;火车订票;线段树用起来太灵活了!;
- codeforces 91B Queue 线段树,简单查询
- 敌兵布阵(简单线段树)
- 线段树之简单方法
- hdu1166 敌兵布阵(线段树 || 树状数组)