现在的位置: 首页 > 综合 > 正文

poj 3468 A Simple Problem with Integers(线段树懒操作)

2013年10月09日 ⁄ 综合 ⁄ 共 1749字 ⁄ 字号 评论关闭

这是我的第一道线段树懒操作,2次TLE,6次WA之后,终于AC了。

其实题目本身没有那么难,不过因为是第一次写,所以很多细节都没注意到。

我在写另一道hdu上的题目的时候,我没有查资料,一直自己yy懒操作该是怎么样。当时我想的是应该是在结点里放一个flag,用来存储对这个结点的子树的更新信息。在更新的时候这个信息并不往下传递,仅仅只是存下来,在需要查询的时候再传递。实际上我想的基本没错,但是当时一个问题卡住我了,那就是,如果我需要查询左子树的值,这时候flag的值需要往左子树更新,那么树根上的flag的值就需要清0。但是右子树怎么办?

这个问题我一直没想到怎么解决,知道我看了别人的思路。。。。。原来只要将这个父节点的flag的值同时传递到它的左右子树就行了。亏我想了那么久,脑子抽筋了。

其他的操作就是线段树的常规操作做了一些小修改,没有什么特别值得一说的地方了。

#include<stdio.h>
#include<string.h>
#define N 100005
struct node
{
	int x,y;
	__int64 sum;
	__int64 flag;
}a[N*3];
int b[N];
void Bulid_Tree(int t,int x,int y)
{
	a[t].x=x;
	a[t].y=y;
	a[t].flag=0;
	if(x==y)
	{
		a[t].sum=b[x];
		return ;
	}
	int temp=t*2;
	int mid=(x+y)/2;
	Bulid_Tree(temp,x,mid);
	Bulid_Tree(temp+1,mid+1,y);
	a[t].sum=a[temp].sum+a[temp+1].sum;
	return ;
}
void Update_Tree(int t,int x,int y,__int64 flag)
{
	if(a[t].x==x&&a[t].y==y)
	{
		a[t].flag+=flag;
		return ;
	}
	a[t].sum=a[t].sum+(y-x+1)*flag;
	int temp=t*2;
	int mid=(a[t].x+a[t].y)/2;
	if(y<=mid)
		Update_Tree(temp,x,y,flag);
	else if(x>mid)
		Update_Tree(temp+1,x,y,flag);
	else
	{
		Update_Tree(temp,x,mid,flag);
		Update_Tree(temp+1,mid+1,y,flag);
	}
	return ;
}
__int64 Find_Tree(int t,int x,int y)
{
	__int64 sum=0;
	if(a[t].x==x&&a[t].y==y)
		return a[t].sum+(a[t].y-a[t].x+1)*a[t].flag;
	int temp=t*2;
	int mid=(a[t].x+a[t].y)/2;
	a[temp].flag+=a[t].flag;
	a[temp+1].flag+=a[t].flag;
	a[t].sum=a[t].sum+(a[t].y-a[t].x+1)*a[t].flag;
	a[t].flag=0;
	if(y<=mid)
		sum+=Find_Tree(temp,x,y);
	else if(x>mid)
		sum+=Find_Tree(temp+1,x,y);
	else
	{
		sum+=Find_Tree(temp,x,mid);
		sum+=Find_Tree(temp+1,mid+1,y);
	}
	return sum;
}
int main()
{
	int n,m;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		int i;
		for(i=1;i<=n;i++)
			scanf("%d",&b[i]);
		Bulid_Tree(1,1,n);
		getchar();
		while(m--)
		{
			char c;
			scanf("%c",&c);
			if(c=='Q')
			{
				int x,y;
				scanf("%d%d",&x,&y);
				getchar();
				printf("%I64d\n",Find_Tree(1,x,y));
			}
			else
			{
				int x,y;
				__int64 z;
				scanf("%d%d%I64d",&x,&y,&z);
				getchar();
				Update_Tree(1,x,y,z);
			}
		}
	}
	return 0;
}

抱歉!评论已关闭.