zoukankan      html  css  js  c++  java
  • 线段树标记永久化

    线段树的标记永久化

    其实线段树的标记永久化是一个非常容易理解的东西,往往我们都会在区间操作时打lazytag,但是在标记下放时会耗费大量的时间,所以我们可以尝试标记永久化,这样我们的就不用下放标记,同时代码也更加简洁,因为我们少了一个pushdown函数,同时出错率也会大大降低。

    首先我们要学会普通的线段树

    这里我们以前在线段树时是使用lazytag来解决区间问题,但是我们会发现在lazytag容易出错,所以我们可以考虑标记永久化,思路也十分清晰

    对于标记永久化,其实和普通线段树比起来,其实差不多

    下面就是一个维护区间和的代码( Luogu3372 【模板】线段树 1)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    
    using namespace std;
    
    typedef long long ll;
    int n,m;
    ll sum[4000001],tag[4000001]; 
    
    
    void pushup(int o){
    	sum[o]=sum[o<<1]+sum[o<<1|1]; 
    }
    
    void build(int o,int l,int r){
    	if(l==r){
    		scanf("%lld",&sum[o]);
    		return;
    	}
    	int mid=(l+r)>>1;
    	build(o<<1,l,mid);
    	build(o<<1|1,mid+1,r);
    	pushup(o);
    }
    
    void update(int o,int l,int r,int x,int y,ll v){
    	sum[o]+=((ll)min(r,y)-(ll)max(x,l)+1)*v;
    	if(x<=l and r<=y){
    		tag[o]+=v;
    		return;
    	}
    	int mid=(l+r)>>1;
    	if(x<=mid){
    		update(o<<1,l,mid,x,y,v);
    	}
    	if(y>mid){
    		update(o<<1|1,mid+1,r,x,y,v);
    	}
    }
    
    ll query(int o,int l,int r,ll tg,int x,int y){
    	if(x<=l and r<=y){
    		return sum[o]+(ll)(min(r,y)-max(x,l)+1)*(tg);
    	}
    	int mid=(l+r)>>1;
    	ll ret=0;
    	if(x<=mid){
    		ret+=query(o<<1,l,mid,tg+tag[o],x,y);
    	}
    	if(y>mid){
    		ret+=query(o<<1|1,mid+1,r,tg+tag[o],x,y);
    	}
    	return ret;
    }
    
    int main(){
    	scanf("%d%d",&n,&m);
    	build(1,1,n);
    	for(int i=1;i<=m;i++){
    		int opt;
    		scanf("%d",&opt);
    		if(opt==1){
    			int x,y;
    			ll z;
    			scanf("%d%d%lld",&x,&y,&z);
    			update(1,1,n,x,y,z);
    		}else{
    			int x,y;
    			scanf("%d%d",&x,&y);
    			printf("%lld
    ",query(1,1,n,0,x,y));
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    excel 读取
    MSDN异步编程概述 [C#] zzhttp://www.cnblogs.com/hxhbluestar/articles/60023.html
    window.opener showModelessDialog showModalDialog 获取|控制父窗体的区别
    MySql中文乱码解决方法
    关于随机数
    javascript 日期处理(注意事项)
    一个简单访问office程序的控件,不依赖officedll
    关于12306的bug
    回车提交
    js动态添加外部js(顶)
  • 原文地址:https://www.cnblogs.com/ezoihy/p/9369730.html
Copyright © 2011-2022 走看看