hdu1166 排兵布阵

题目链接:点击打开链接

题目大意:

    多组数据,单点更新,区间查询

思路:

    裸的线段树,手打了一遍练练感觉,但是问题还是挺多的;

    总结一下,

    (1)单点更新时,以mid作为基准,如果mid>=id查左边的,如果mid<id查右边的;

    (2)build的时候,要理清思路,先给树的左右节点位置赋值;

    (3)查询时,应该以当前树的L和R算出mid,设查询区间为(l,r),如果l<=mid,则查询左子树,否则查右子树,最后一步才返回ans;

    (4)当读到End的时候,是没有输入的!!!这一点卡了很久!!!、

#include<bits/stdc++.h>
using namespace std;
const int maxn = 50005;
typedef long long ll;
ll t,n,a[maxn];

struct node{
	ll l,r;
	ll sum;
	ll lazy;
	void update(ll x)
	{
		sum += (r-l+1)*x;	
		lazy += x;
	}
}tree[maxn*4];

void push_up(int x)
{
	tree[x].sum = tree[x<<1].sum+tree[x<<1|1].sum;
}

void push_down(int x)
{
	if(tree[x].lazy)
	{
		int lazyval = tree[x].lazy;
		tree[x<<1].update(lazyval);
		tree[x<<1|1].update(lazyval);
		tree[x].lazy = 0;
	}	
}

void build(int x,int l,int r)
{
	tree[x].l = l;
	tree[x].r = r;
	tree[x].sum = tree[x].lazy = 0;
	if(l==r)
	{
		tree[x].sum = a[l];
		return;
	}		
	int mid = (l+r)/2;
	build(x<<1,l,mid);
	build(x<<1|1,mid+1,r);
	push_up(x);
}

void update(int x,int id,int val)
{
	int l = tree[x].l;
	int r = tree[x].r;
//	cout<<l<<" "<<r<<" "<<tree[x].sum<<endl;
	if(l==id&&r==id)
	{
		tree[x].update(val);
		return;
	}
	int mid = (l+r)/2;
	push_down(x);
	if(id<=mid)
		update(x<<1,id,val);
	if(id>mid)
		update(x<<1|1,id,val);
	push_up(x);
}

long long query(int x,int l,int r)
{
	ll ans = 0;
	int L = tree[x].l;
	int R = tree[x].r;
	//cout<<L<<" "<<R<<" "<<tree[x].sum<<endl;
	if(l<=L&&r>=R)
		ans += tree[x].sum;
	else {
		int mid = (L+R)/2;
		if(l<=mid)
			ans += query(x<<1,l,r);
		if(r>mid)
			ans += query(x<<1|1,l,r);
	}
	return ans;	
}

int main()
{
	//freopen("d://test.txt","r",stdin);
	cin>>t;
	int cnt = 1;
	while(cnt<=t)
	{	
		cout<<"Case "<<cnt++<<":"<<endl;
		cin>>n;
//		cout<<n<<endl;
		memset(a,0,sizeof(a));
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		build(1,1,n);
		string s;
		while(cin>>s)
		{
			int x,y;
			if(s[0]=='A')
			{
				scanf("%d%d",&x,&y);
				update(1,x,y);
			}
			else if(s[0]=='S')
			{
				scanf("%d%d",&x,&y);
				update(1,x,-y);
			}
			else if(s[0]=='Q')
			{
				scanf("%d%d",&x,&y);
				cout<<query(1,x,y)<<endl;
			}
			else if(s[0]=='E')
			{
				break;
			}
		}
	}	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zxwsbg/article/details/80283130