#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\n",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\n",Query(1,1,N));
    }
	fclose(stdin);
    return 0;
}

相关文章:

  • 2021-10-22
  • 2021-12-05
  • 2021-05-21
  • 2022-02-24
  • 2021-09-18
  • 2021-11-11
  • 2021-09-21
猜你喜欢
  • 2021-08-04
  • 2022-12-23
  • 2021-11-10
  • 2021-05-21
  • 2021-10-21
  • 2021-11-26
相关资源
相似解决方案