hdu 1698 线段数的区间更新 以及延迟更新

先说说区间更新和单点更新的区别 主要的区别是搜索的过程 前者需要确定一个区间 后者就是一个点就好了

贴上两者代码

void updata(int i)//单点更新
{
	int l=stu[i].l;
	int r=stu[i].r;
	int mid=(l+r)/2;//二分咯
	if(l==r&&r==x)//x为目标id 当左右节点相同的时候 就是找到这个数的时候
	{
		stu[i].maxx=y;
		return;
	} 
	if(l<=x&&x<=mid) updata(i*2);//向左找
	else updata(i*2+1);//向右找
	stu[i].maxx=max(stu[i*2].maxx,stu[i*2+1].maxx);//回溯的时候 更新max的数据
}
void update(int l,int r,int count)//x,y代表要更新的区间 //区间更新
{
	if(l>=x&&r<=y) 
	{
		mapp[count].sum=z*mapp[count].len;
		mapp[count].flag=z;
		return;
	}
	pushdown(count);	
	int mid=(l+r)/2;
    if(x<=mid) update(l,mid,count*2);  
    if(y>=mid+1) update(mid+1,r,count*2+1);  
    mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; 
}
在区间更新的时候 有的时候 我们不需要更新到底部 那么 这里引进一个延迟更新的概念 在搜索包含在我们需要的区间里面时 就可以返回了

那么在下次询问的时候 怎么保证底层的数据更新呢? 这里需要一个flag标记 如果当前的flag不为0的时候 向下更新 并更改当前的flag


比如在1-10标号的区间里面 我们要更新1-5的值
上代码

#include<iostream>
#define maxn 111111
using namespace std;
int n,q,x,y,z;
struct stu
{
	int l,r,sum,flag,len;
};
stu mapp[maxn*4];
void build(int l,int r,int count)
{
	mapp[count].l=l;
	mapp[count].r=r;
	mapp[count].flag=0;
	mapp[count].len=r-l+1;
	if(l==r)
	{
		mapp[count].sum=1;
		mapp[count].flag=1;
		return;
	}
	int mid=(l+r)/2;
	build(l,mid,count*2);  
    build(mid+1,r,count*2+1);  
    mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum;  
}
void pushdown(int count)
{
	if(mapp[count].flag)//如果有标记 向下更新
	{
		mapp[count*2].flag=mapp[count].flag;  
        mapp[count*2+1].flag=mapp[count].flag;
        mapp[count*2].sum=mapp[count].flag*mapp[count*2].len;  
        mapp[count*2+1].sum=mapp[count].flag*mapp[count*2+1].len;
        mapp[count].flag=0;//更新过一次  标记得消除
	}
}//向下更新的过程
void update(int l,int r,int count)//x,y代表要更新的区间 
{
	if(l>=x&&r<=y)
	if(l==r) 
	{
		mapp[count].sum=z*mapp[count].len;
		mapp[count].flag=z;
		return;
	}
	pushdown(count);	
	int mid=(l+r)/2;
	if(x<=mid) update(l,mid,count*2);  
    if(y>=mid+1) update(mid+1,r,count*2+1);  
    mapp[count].sum=mapp[count*2].sum+mapp[count*2+1].sum; 
}
int main()
{
	cin.sync_with_stdio(false);  
	int t;
	cin>>t;
	int casee=1;
	while(t--)
	{
		cin>>n;
		build(1,n,1);
		cin>>q;
		while(q--)
		{
			cin>>x>>y>>z;
			update(1,n,1);
		}
		cout<<"Case "<<casee++<<": The total value of the hook is ";  
        cout<<mapp[1].sum<<"."<<endl;  
	}
	return 0;
} 
原文地址:https://www.cnblogs.com/z1141000271/p/5732790.html