您的位置:首页 > 其它

hdu1166 线段树单点更新区间查询

2018-02-25 13:52 441 查看

题意:

单点修改:人数+= c
区间查询:【l,r】人数和

思路:

单点暴力修改到叶子
区间信息:维护加法和

难度:0.5

866ms
#include<stdio.h>
#include<math.h>
#include<iostream>
using namespace std;
const int inf=0x3f3f3f;
struct Stree
{
int val;//sum
//int lazy;
} sts[4*50005]; //开4倍
int a[50005];

int pushup(int root)
{
sts[root].val=sts[root<<1].val+sts[root<<1|1].val;
}
void build(int l,int r,int root)//根节点从1开始吧
{
if(l==r)//到达子节点
{
sts[root].val=a[l];
}
else
{
//sts[root].val=sts[root].lazy=0;//没了这句会WA,清空lazy跟val
int mid=(l+r)>>1;//(l+r)/2
build(l,mid,root<<1);
build(mid+1,r,root<<1|1);
pushup(root);//更新本节点
}
}
int query(int nowl,int nowr,int ql,int qr,int root)
{
if(nowl>=ql&&nowr<=qr)
{
return sts[root].val;
}
// pushdown(root);
int mid=(nowl+nowr)>>1;
int ans=0;
if(ql<=mid)ans+=query(nowl,mid,ql,qr,root<<1);
if(qr>mid)ans+=query(mid+1,nowr,ql,qr,root<<1|1);
return ans;
}
void updateone(int nowl,int nowr,int idx,int addval,int root)
{
if(nowl==nowr)
{
if(idx==nowl) sts[root].val+=addval;
return ;
}
// pushdown(root);
int mid=(nowl+nowr)>>1;
if(idx<=mid)
updateone(nowl,mid,idx,addval,root<<1);
else
updateone(mid+1,nowr,idx,addval,root<<1|1);
pushup(root);
}

int main()
{
int T;
cin>>T;
int kase=0;
while(T--)
{
int n;
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,n,1);
// op(n);
string s;int l,r;
printf("Case %d:\n",++kase);
while(cin>>s)
{
if(s[0]=='E')break;
scanf("%d %d",&l,&r);
if(s[0]=='A')
updateone(1,n,l,r,1);
else if(s[0]=='S')
updateone(1,n,l,-r,1);
else if(s[0]=='Q')
printf("%d\n",query(1,n,l,r,1));
}
}
}

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