HDU1698线段树区间更新

lazy思想
每次更新只要更新到题目要求的区间即可,然后更新此区间节点data值,
记录tree[num].lazy(等于题目要求更新的值wei),
下次要用到的时候就传递给左右子树,更新左右子树的data值。

并且将当前lazy归0.

运用lazy思想,就不用每次都更新(或查找)到叶子节点,在某些数据比较大的时候会节省很多时间。

HDU1698为例

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct node
{
	int l,r,m,data,lazy;
}tree[3*100005];

void creat(int num,int le,int ri)
{
	tree[num].l=le;
	tree[num].r=ri;
	tree[num].m=(le+ri)/2;	
	if(le==ri)
	{
		tree[num].data=1;
		tree[num].lazy=0;
		return ;		
	}
	creat(2*num,le,tree[num].m);
	creat(2*num+1,tree[num].m+1,ri);	
}

void insert(int num,int le,int ri,int k)
{	
	if(tree[num].l==le&&tree[num].r==ri)
	{
		tree[num].data=(ri-le+1)*k;   //找到后更新data
		tree[num].lazy=k;		      //lazy标记
		return ;
	}
	if(tree[num].lazy!=0)     //重点!!!是否之前有遍历过
	{
		tree[2*num].lazy=tree[num].lazy;    //将lazy传递给左子树
		tree[2*num+1].lazy=tree[num].lazy;   //传递给右子树
		tree[2*num].data=(tree[2*num].r-tree[2*num].l+1)*tree[num].lazy;   //更新左右子树的data值
		tree[2*num+1].data=(tree[2*num+1].r-tree[2*num+1].l+1)*tree[num].lazy;
		tree[num].lazy=0;     //将当前区间节点归零,会有返回值更新data值。
	}
	if(ri<=tree[num].m)
		insert(2*num,le,ri,k);
	else if(le>tree[num].m)
		insert(2*num+1,le,ri,k);
	else
	{
		insert(2*num,le,tree[num].m,k);
		insert(2*num+1,tree[num].m+1,ri,k);
	}
	tree[num].data=tree[2*num].data+tree[2*num+1].data;
}

int main()
{
	int t,n,le,ri,wei,i,q,j;
	scanf("%d",&t);
		for(i=1;i<=t;i++)
		{
			memset(tree,0,sizeof(tree));    //每次最好都初始化线段树。此题没初始化WA!!!
			scanf("%d%d",&n,&q);
			creat(1,1,n);
			for(j=1;j<=q;j++)
			{
				scanf("%d%d%d",&le,&ri,&wei);
				insert(1,le,ri,wei);
			}
			printf("Case %d: The total value of the hook is %d.\n",i,tree[1].data);
		}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值