• 线段树1 2


    动态开点-指针

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    const long long  k=5e5+5;
    
    long long  a[k];
    
    struct Segment{
        long long  l,r;
        long long  sum;
        long long  tag;
        Segment *lef,*rig;
        
        Segment(const long long  L,const long long  R ) : l(L),r(R),sum(0),tag(0),lef(NULL),rig(NULL) {} 
        
        inline void maketag(const long long  val){
            sum+=val*(r-l+1);
            tag+=val;
        }
        
        void spread()
        {
            long long  mid=(l+r)>>1;
            if(lef == NULL) lef=new Segment(l,mid);
            if(rig == NULL) rig =new Segment(mid+1,r);
            if(tag==0) return;
            else {
                lef->maketag(tag);
                rig->maketag(tag);
                tag=0;
            }
        }    
    
        inline bool Out(const long long  L,const long long  R) { return (R<l || r<L ) ;}
    
        void change(long long  L,long long  R,long long  val)
        {
            if(L<=l && r<=R){
                maketag(val);
            }
            else {
                if(Out(L,R)) return ;
                else{
                spread();
                lef->change(L,R,val);
                rig->change(L,R,val);
                sum=lef->sum+rig->sum;
                } 
                
            }
        }
        
        
        long long  ask(long long  L,long long  R)
        {
            if(L<=l && r<=R) return sum;
            else {
                if(Out(L,R)) return 0;
                else{
                spread();
                return lef->ask(L,R)+rig->ask(L,R);
                
                } 
                
            }
        }
        
    };
    
    Segment *root;
    
    int  main(void)
    {
        long long  n,m,q;
        
        ios_base::sync_with_stdio(false);
        cout.tie(NULL);
        cin.tie(NULL);
        
        cin>>n>>m;
        
        root=new Segment(1,n);
        
        for(long long  i=1;i<=n;i++)
        {
            cin>>q;
            root->change(i,i,q);
        }
        
        
        
        for(long long  i=1;i<=m;i++)
        {
            long long  x,y,z,g;
            cin>>x>>y>>z;
            
            if(x==1){
                cin>>g;
                root->change(y,z,g);
            }
            else {
                cout<<root->ask(y,z)<<'
    ';
            }
        }
    }
    

    数组线段树

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    #define ls(x) x<<1
    #define rs(x) x<<1|1
    
    long long n,m;
    long long a[500005];
    
    struct node{
    	long long sum;
    	long long left,right;
    	long long tag;
    }t[500005];
    
    void build(long long root,long long lef,long long rig)
    {
    	t[root].left =lef;
    	t[root].right =rig;
    	if(lef == rig)
    	{
    		t[root].sum =a[lef];
    		return;
    	}
    	long long mid=lef+rig>>1;
    	build(ls(root),lef,mid);
    	build(rs(root),mid+1,rig);
    	t[root].sum = t[ls(root)].sum + t[rs(root)].sum; 
    }
    
    void spread(long long root)
    {
    	if(t[root].tag)
    	{
    //		t[root].sum =t[root].sum +t[root].tag ;
    		t[ls(root)].sum +=t[root].tag * (t[ls(root)].right -t[ls(root)].left+1 );
    		t[rs(root)].sum +=t[root].tag * (t[rs(root)].right -t[rs(root)].left+1 );
    		t[rs(root)].tag +=t[root].tag;
    		t[ls(root)].tag +=t[root].tag;
    		t[root].tag =0;
    		
    	}
    }
    
    void change(long long r,long long lef,long long rig,long long dis)
    {
    	if(lef<=t[r].left && rig>=t[r].right )
    	{
    		t[r].sum += dis *(t[r].right -t[r].left +1 );
    		t[r].tag +=dis;
    		return ;
    	}
    	spread(r);
    	long long mid=t[r].left +t[r].right>>1;
    	if(lef<=mid) change(ls(r),lef,rig,dis);
    	if(rig>mid) change(rs(r),lef,rig,dis);
    	t[r].sum =t[ls(r)].sum +t[rs(r)].sum;
    	
    }
    
    long long ask(long long r,long long lef,long long rig)
    {
    	if(lef<=t[r].left &&rig>=t[r].right ) return t[r].sum ;
    	spread(r);
    	long long ans=0;
    	long long mid=t[r].left +t[r].right>>1;
    	if(lef<=mid) ans+=ask(ls(r),lef,rig);
    	if(rig>mid) ans+=ask(rs(r),lef,rig);
    	return ans;
    	
    }
    
    int main()
    {
    	long long x,y,z,k;
    	
    	ios_base::sync_with_stdio(false);
    	cout.tie(NULL);
    	
    	cin>>n>>m;
    	
    	for(long long i=1;i<=n;i++)
    	cin>>a[i];
    	
    	build(1,1,n);
    	
    	for(long long i=1;i<=m;i++)
    	{
    		cin>>k;
    		if(k==1)
    		{
    			cin>>x>>y>>z;
    			change(1,x,y,z);
    		}
    		if(k==2)
    		{
    			cin>>x>>y;
    			cout<<ask(1,x,y)<<'
    ';
    		}
    	}
    
    

    线段树2

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    const long long  k=5e5+5;
    
    long long  a[k];
    long long p;
    
    struct Segment{
    	long long  l,r;
    	long long  sum;
    	long long  tag;
    	long long tag_x;
    	Segment *lef,*rig;
    	
    	Segment(const long long  L,const long long  R ) : l(L),r(R),sum(0),tag(0),tag_x(1),lef(NULL),rig(NULL) {} 
    	
    	inline void maketage(const long long mul,const long long add) 
    	{
    		sum=(mul *sum)%p + ((r-l+1)*add)%p;
    		sum%=p;
    		tag_x*=mul;
    		tag_x%=p;
    		tag=(tag * mul +add)%p;
    		
    	}
    	
    	void spread()
    	{
    		long long  mid=(l+r)>>1;
    		
    		if(lef == NULL) lef=new Segment(l,mid);
    		if(rig == NULL) rig =new Segment(mid+1,r);
    	
    		if(tag==0 && tag_x == 1) return;
    		else {
    			lef->maketage(tag_x,tag);
    			rig->maketage(tag_x,tag);
    			tag=0;
    			tag_x=1;
    		}
    	}	
    
    	inline bool Out(const long long  L,const long long  R) { return (R<l || r<L ) ;}
    
    	void change(long long  L,long long  R,long long  val)
    	{
    		if(L<=l && r<=R){
    			maketage(1,val);
    		}
    		else {
    			if(Out(L,R)) return ;
    			else{
    			spread();
    			lef->change(L,R,val);
    			rig->change(L,R,val);
    			sum=lef->sum+rig->sum;
    			sum%=p;
    			} 
    			
    		}
    	}
    	
    	void change_x(long long  L,long long  R,long long  val)
    	{
    		if(L<=l && r<=R){
    			maketage(val,0);
    		}
    		else{
    			if(Out(L,R)) return ;
    			else{
    				spread();
    				lef->change_x(L,R,val);
    				rig->change_x(L,R,val);
    				sum=lef->sum + rig->sum ; 
    				sum%=p; 
    			}
    		}
    	}
    	
    	
    	long long  ask(long long  L,long long  R)
    	{
    		if(L<=l && r<=R) return sum%p;
    		
    		else {
    			
    			if(Out(L,R)) return 0;
    			
    			else{
    			
    			spread();
    			
    			return (lef->ask(L,R)%p) + (rig->ask(L,R)%p);
    			
    			} 
    			
    		}
    	}
    	
    };
    
    Segment *root;
    
    int  main(void)
    {
    	long long  n,m,q;
    	
    	ios_base::sync_with_stdio(false);
    	cout.tie(NULL);
    	cin.tie(NULL);
    	
    	cin>>n>>m>>p;
    	
    	root=new Segment(1,n);
    	
    	for(long long  i=1;i<=n;i++)
    	{
    		cin>>q;
    		root->change(i,i,q);
    	}
    	
    	
    	
    	for(long long  i=1;i<=m;i++)
    	{
    		long long  x,y,z,g;
    		cin>>x>>y>>z;
    		
    		if(x==2){
    			cin>>g;
    			root->change(y,z,g);
    		}
    		if(x== 3) {
    			cout<<root->ask(y,z)%p<<'
    ';
    		}
    		if(x== 1)
    		{
    			cin>>g;
    			root->change_x(y,z,g); 
    		}
    	}
    }
    

    end

  • 相关阅读:
    Windows10下Opencv4+CMake+MinGW64+VSC安装教程
    相机标定问题-实践操作流程
    eNSP仿真学习,网络入门!
    SFTP服务的使用!!
    树莓派B+使用入门&RPI库安装&wringPi库安装
    Python基本语法初试
    基于51单片机+DAC0832的信号发生器
    各种标志位的含义
    根文件系统ramdisk.image.gz && uramdisk.image.gz
    Linux中/etc/inittab文件
  • 原文地址:https://www.cnblogs.com/-Iris-/p/13253358.html
Copyright © 2020-2023  润新知