zoukankan      html  css  js  c++  java
  • 线段树模板【数据结构

    单点更新,区间最小值

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define TREE_SIZE (1<<(20))
    //#define local
    
    class IntervalTree
    {
    	private:	
    		// Top 重要
    		int Top[TREE_SIZE];
    		int size;
    		int _Query(int a,int b,int l,int r,int Ind)
    		{
    			if(a<=l&& b>=r)return  Top[Ind];
    			int mid=(l+r)>>1,ret=INF;
    			if(a<=mid) ret=min(ret,_Query(a,b,l,mid,Ind<<1));
    			if(b>mid) ret=min(ret,_Query(a,b,mid+1,r,(Ind<<1)+1));
    			return ret;			
    		}
    		void _Modify(int a,int l,int r,int Ind,int d)
    		{
    			if(l==r && l==a)
    			{
    				Top[Ind]=d;				
    				return ;
    			}
    			int mid=(l+r)>>1;
    			if(a<=mid) _Modify(a,l,mid,Ind<<1,d);
    			else _Modify(a,mid+1,r,(Ind<<1)+1,d);
    			Top[Ind]=min(Top[Ind<<1],Top[(Ind<<1)+1]);
    		}
    		public:
    			IntervalTree()
    			{
    				//memset(Cover,INF,sizeof(Cover));
    				memset(Top,INF,sizeof(Top));
    				size=(TREE_SIZE>>2)-1;
    			}
    			IntervalTree(int size):size(size)
    			{
    				//memset(Cover,INF,sizeof(Cover));
    				memset(Top,INF,sizeof(Top));
    			}
    			int Query(int a,int b)
    			{
    				return _Query(a,b,1,size,1);
    			}
    			void Modify(int a,int d)
    			{
    				return _Modify(a,1,size,1,d);
    			}
    }it;
    
    int main()
    {
    	#ifdef LOCAL
        freopen("a.txt", "r", stdin);
        #endif
    	//IntervalTree (*it)=new IntervalTree(7);
    	(it).Modify(1,2);	
    	(it).Modify(2,8);
    	(it).Modify(3,4);
    	(it).Modify(4,1);
    	(it).Modify(5,6);
    	(it).Modify(6,7);
    	(it).Modify(7,3);
    	
    	cout<<(it).Query(5,6)<<endl;	
    	cout<<(it).Query(3,4)<<endl;
    	cout<<(it).Query(1,7)<<endl;	
    	cout<<(it).Query(1,3)<<endl;
    	
    	fclose(stdin);
    	return 0;
    }
    
    

    单点更新,区间最大值

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define TREE_SIZE (1<<(20))
    //#define local
    
    class IntervalTree
    {
    	private:	
    		// Top 重要
    		int Top[TREE_SIZE];
    		int size;
    		int _Query(int a,int b,int l,int r,int Ind)
    		{
    			if(a<=l&& b>=r)return  Top[Ind];
    			int mid=(l+r)>>1,ret=0;
    			if(a<=mid) ret=max(ret,_Query(a,b,l,mid,Ind<<1));
    			if(b>mid) ret=max(ret,_Query(a,b,mid+1,r,(Ind<<1)+1));
    			return ret;			
    		}
    		void _Modify(int a,int l,int r,int Ind,int d)
    		{
    			if(l==r && l==a)
    			{
    				Top[Ind]=d;				
    				return ;
    			}
    			int mid=(l+r)>>1;
    			if(a<=mid) _Modify(a,l,mid,Ind<<1,d);
    			else _Modify(a,mid+1,r,(Ind<<1)+1,d);
    			Top[Ind]=max(Top[Ind<<1],Top[(Ind<<1)+1]);
    		}
    		public:
    			IntervalTree()
    			{
    				//memset(Cover,0,sizeof(Cover));
    				memset(Top,0,sizeof(Top));
    				size=(TREE_SIZE>>2)-1;
    			}
    			IntervalTree(int size):size(size)
    			{
    				//memset(Cover,0,sizeof(Cover));
    				memset(Top,0,sizeof(Top));
    			}
    			int Query(int a,int b)
    			{
    				return _Query(a,b,1,size,1);
    			}
    			void Modify(int a,int d)
    			{
    				return _Modify(a,1,size,1,d);
    			}
    }it;
    
    int main()
    {
    	#ifdef LOCAL
        freopen("a.txt", "r", stdin);
        #endif
    	//IntervalTree (*it)=new IntervalTree(7);
    	(it).Modify(1,2);	
    	(it).Modify(2,8);
    	(it).Modify(3,4);
    	(it).Modify(4,1);
    	(it).Modify(5,6);
    	(it).Modify(6,7);
    	(it).Modify(7,3);
    	
    	cout<<(it).Query(5,6)<<endl;	
    	cout<<(it).Query(3,4)<<endl;
    	cout<<(it).Query(1,7)<<endl;	
    	cout<<(it).Query(1,3)<<endl;
    	
    	fclose(stdin);
    	return 0;
    }
    
    

    单点更新,区间求和

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define TREE_SIZE (1<<(20))
    //#define local
    
    class IntervalTree
    {
    	private:	
    		// Top 重要
    		int Top[TREE_SIZE];
    		int size;
    		int _Query(int a,int b,int l,int r,int Ind)
    		{
    			if(a<=l&& b>=r)return  Top[Ind];
    			int mid=(l+r)>>1,ret=0;
    			if(a<=mid) ret+=_Query(a,b,l,mid,Ind<<1);
    			if(b>mid) ret+=_Query(a,b,mid+1,r,(Ind<<1)+1);
    			return ret;			
    		}
    		void _Modify(int a,int l,int r,int Ind,int d)
    		{
    			if(l==r && l==a)
    			{
    				Top[Ind]=d;				
    				return ;
    			}
    			int mid=(l+r)>>1;
    			if(a<=mid) _Modify(a,l,mid,Ind<<1,d);
    			else _Modify(a,mid+1,r,(Ind<<1)+1,d);
    			Top[Ind]=Top[Ind<<1]+Top[(Ind<<1)+1];
    		}
    		public:
    			IntervalTree()
    			{
    				//memset(Cover,0,sizeof(Cover));
    				memset(Top,0,sizeof(Top));
    				size=(TREE_SIZE>>2)-1;
    			}
    			IntervalTree(int size):size(size)
    			{
    				//memset(Cover,0,sizeof(Cover));
    				memset(Top,0,sizeof(Top));
    			}
    			int Query(int a,int b)
    			{
    				return _Query(a,b,1,size,1);
    			}
    			void Modify(int a,int d)
    			{
    				return _Modify(a,1,size,1,d);
    			}
    }it;
    
    int main()
    {
    	#ifdef LOCAL
        freopen("a.txt", "r", stdin);
        #endif
    	//IntervalTree (*it)=new IntervalTree(7);
    	(it).Modify(1,2);	
    	(it).Modify(2,8);
    	(it).Modify(3,4);
    	(it).Modify(4,1);
    	(it).Modify(5,6);
    	(it).Modify(6,7);
    	(it).Modify(7,3);
    	
    	cout<<(it).Query(5,6)<<endl;	
    	cout<<(it).Query(3,4)<<endl;
    	cout<<(it).Query(1,7)<<endl;	
    	cout<<(it).Query(1,3)<<endl;
    	
    	fclose(stdin);
    	return 0;
    }
    
    

    区间替换,区间求和

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    
    const int MAX=1008600;
    
    int sum[MAX<<2],flag[MAX<<2];
    
    inline void PushUp(int idx)
    {
        sum[idx]=sum[idx<<1]+sum[idx<<1|1];
    }
    
    void Build(int idx,int left,int right)
    {
        // flag : -1表示没有懒惰标记
        flag[idx]=-1;
        if(left==right)
        {
            scanf("%d",sum+idx);
            return ;
        }
        int mid=(left+right)>>1;
        Build(idx<<1,left,mid);
        Build(idx<<1|1,mid+1,right);
        PushUp(idx);
    }
    
    // 懒惰标记的‘下放操作’
    inline void PushDown(int idx,int left,int mid)
    {
        int L=idx<<1,R=L+1;
        sum[L]=(mid-left+1)*flag[idx];
        sum[R]=sum[idx]-sum[L];
        flag[L]=flag[R]=flag[idx];
        flag[idx]=-1;
    }
    
    int L,R,val;
    
    void Update(int idx,int left,int right)
    {
        if(L<=left && right<=R)
        {
            sum[idx]=(right-left+1)*val;
            // 放置懒惰标记
            flag[idx]=val;
            return;
        }
        int mid=(left+right)>>1;
        if(flag[idx]!=-1) PushDown(idx,left,mid);
        if(L<=mid) Update(idx<<1,left,mid);
        if(mid<R) Update(idx<<1|1,mid+1,right);
        PushUp(idx);
    }
    
    int Query(int idx,int left,int right)
    {
        if(L<=left && right<=R)
            return sum[idx];
        int mid=(left+right)>>1,ans=0;
        if(flag[idx]!=-1) PushDown(idx,left,mid);
        if(L<=mid) ans+=Query(idx<<1,left,mid);
        if(mid<R) ans+=Query(idx<<1|1,mid+1,right);
        return ans;
    }
    
    int main()
    {
        //freopen("test.txt","r",stdin);
        int N,i,M;
        scanf("%d",&N);
        Build(1,1,N);	
        scanf("%d",&M);
        while(M--)
        {
            scanf("%d%d%d",&i,&L,&R);
            if(i)
            {
                scanf("%d",&val);
                Update(1,1,N);
            }
            else printf("%d
    ",Query(1,1,N));
        }
        return 0;
    }
    

    区间更新(加上一个数字),区间求和

    // 线段树_区间修改区间求和
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int MAX=1008600;
    int sum[MAX<<2],flag[MAX<<2];
    inline void PushUp(int idx){
        sum[idx]=sum[idx<<1]+sum[idx<<1|1];
    }
    void Build(int idx,int left,int right){
        // flag : -1表示没有懒惰标记
        flag[idx]=-1;
        if(left==right)
        {
            scanf("%d",sum+idx); return ;
        }
        int mid=(left+right)>>1;
        Build(idx<<1,left,mid);
        Build(idx<<1|1,mid+1,right);
        PushUp(idx);
    }
    // 懒惰标记的‘下放操作’
    inline void PushDown(int idx,int left,int mid){
        int L=idx<<1,R=L+1;
        sum[L]=(mid-left+1)*flag[idx];
        sum[R]=sum[idx]-sum[L];
        flag[L]=flag[R]=flag[idx];
        flag[idx]=-1;
    }
    int L,R,val;
    void Update(int idx,int left,int right){
        if(L<=left && right<=R){
            sum[idx]+=(right-left+1)*val;
            // 放置懒惰标记
            flag[idx]+=val;
            return;
        }
        int mid=(left+right)>>1;
        if(flag[idx]!=-1) PushDown(idx,left,mid);
        if(L<=mid) Update(idx<<1,left,mid);
        if(mid<R) Update(idx<<1|1,mid+1,right);
        PushUp(idx);
    }
    
    int Query(int idx,int left,int right){
        if(L<=left && right<=R)
            return sum[idx];
        int mid=(left+right)>>1,ans=0;
        if(flag[idx]!=-1) PushDown(idx,left,mid);
        if(L<=mid) ans+=Query(idx<<1,left,mid);
        if(mid<R) ans+=Query(idx<<1|1,mid+1,right);
        return ans;
    }
    
    int main()
    {
        freopen("C:\Users\ssw\Desktop\test.txt","r",stdin);
        int N,i,M;
        scanf("%d",&N);
        Build(1,1,N);	
        scanf("%d",&M);
        while(M--){
            scanf("%d%d%d",&i,&L,&R);
            if(i){
                scanf("%d",&val);
                Update(1,1,N);
            }
            else printf("%d
    ",Query(1,1,N));
        }
    	fclose(stdin);
        return 0;
    }
    
  • 相关阅读:
    我与计算机
    C高级第四次作业
    C高级第三次作业
    C高级第二次作业
    C高级第一次PTA作业 要求三
    C高级第一次PTA作业
    第0次作业
    # 20182304 实验七 《数据结构与面向对象程序设计》实验报告
    # 20182304 实验八 《数据结构与面向对象程序设计》实验报告
    # 20182304 《数据结构与面向对象程序设计》第八周学习总结
  • 原文地址:https://www.cnblogs.com/shengwang/p/9848538.html
Copyright © 2011-2022 走看看