线段树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)<<'\n';
        }
    }
}

数组线段树

#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)<<'\n';
		}
	}

线段树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<<'\n';
		}
		if(x== 1)
		{
			cin>>g;
			root->change_x(y,z,g); 
		}
	}
}

end

posted @ 2020-07-06 10:03  ·Iris  阅读(194)  评论(2编辑  收藏  举报