敌兵布阵 HDU 1166 线段树

敌兵布阵 HDU 1166 线段树

题意

这个题是用中文来描写的,很简单,没什么弯。

解题思路

这个题肯定就是用线段树来做了,不过当时想了一下可不可用差分来做,因为不熟练就还是用了线段树来做,几乎就是模板题了。

代码实现

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
# define ls (rt<<1)
# define rs (rt<<1|1)
using namespace std;
const int  maxn=5e4+7;
struct node{
	int l, r;
	int sum, lazy;
}t[maxn<<2];
int num[maxn];
int n, m;
void up(int rt)
{
	t[rt].sum=t[ls].sum+t[rs].sum;
}
void build(int rt, int l, int r)
{
	t[rt].l=l;
	t[rt].r=r;
	t[rt].lazy=0;
	if(l==r)
	{
		t[rt].sum=num[l];
		return ;
	}
	int  mid=(l+r)>>1;
	build(ls, l, mid);
	build(rs, mid+1, r);
	up(rt);
}
void down(int rt)
{
	if(t[rt].lazy!=0)
	{
		t[ls].lazy+=t[rt].lazy;
		t[ls].sum+=t[rt].lazy;
		
		t[rs].lazy+=t[rt].lazy;
		t[rs].sum+=t[rt].lazy;
		
		t[rt].lazy=0;
	}
}
void update(int rt, int x, int v)
{
	if(t[rt].l == t[rt].r )
	{
		t[rt].lazy+=v;
		t[rt].sum+=v;
		return ;
	}
	down(rt);
	int mid=(t[rt].l+t[rt].r)>>1;
	if(x<=mid) update(ls, x, v);
	else  update(rs, x, v);
	up(rt);
}
int query(int rt, int l, int r)
{
	if(l <= t[rt].l && t[rt].r <= r)
	{
		return t[rt].sum;
	}
	down(rt);
	int ans=0;
	int mid=(t[rt].l+t[rt].r)>>1;
	if(l<=mid) ans+=query(ls, l, r);
	if(r>mid) ans+=query(rs, l, r);
	return ans;
}
int main()
{
	int t;
	scanf("%d", &t);
	for(int ca=1; ca<=t; ca++)
	{
		scanf("%d", &n);
		for(int i=1; i<=n; i++)
		{
			scanf("%d", &num[i]);
		}
		build(1, 1, n);
		string op;
		int x, y;
		printf("Case %d:
", ca);
		while(cin >> op && op!="End")
		{
			scanf("%d%d", &x, &y);
			if(op=="Query")
			{
				printf("%d
", query(1, x, y));
			}
			else if(op=="Add")
			{
				update(1, x, y);
			}
			else update(1, x, -y);
		}
	}
	return 0;
}
欢迎评论交流!
原文地址:https://www.cnblogs.com/alking1001/p/11405949.html