线段树的一种简单实现

发现之前没有整理过线段树的代码,填一下坑。

下面是洛谷P3372的模板代码。

#include<cstdio>
#include<iostream>
#include<vector>

#define int long long

namespace Zhang_Tao
{
	inline int Read_Int(int &x)
	{
		x = 0;
		int fh = 1;
		char ch = getchar();
		while(!isdigit(ch))
		{
			if(ch == '-')
				fh=-1;
			ch=getchar();
		}
		while(isdigit(ch))
		{
			x = x * 10 + ch -'0';
			ch=getchar();
		}
		return x*=fh;
	}
	//Read an int fastly
	void Write_Int(int x)
	{
		if(x < 0)
			putchar('-'),x *= -1;
		if(x > 9)
			Write_Int(x / 10);
		putchar(x % 10 + 48);
	}
	//Write an int Fastly
	inline int Get_GCD(const int x,const int y)
	{
		return y ? Get_GCD(y,x % y) : x;
	}
	//Get GCD of x and y
	inline void Swap(int &x,int &y)
	{
		x ^= y ^= x ^= y;
	}
	//Change two numbers
}//namespace Zhang_Tao


#ifndef MAXN
#define MAXN 100005
#endif

using namespace Zhang_Tao;
using namespace std;

int N,M;
int Array[MAXN];

class SegmentTree
{
	public:
		SegmentTree(){}

		static SegmentTree* BuildTree(const int L,const int R)
		{
			SegmentTree *u = new SegmentTree;
			u -> l = L,u -> r = R;
			u -> Tag = 0;
			if(L == R)
			{
				u -> Lson = u -> Rson = nullptr;
				u -> Sum = Array[L];
			}
			else
			{
				int Mid = (L + R) >> 1;
				u -> Lson = BuildTree(L,Mid);
				u -> Rson = BuildTree(Mid + 1,R);
				u -> Update();
			}
			return u;
		}

		inline bool InRange(const int L,const int R)
		{
			return (L <= l) and (r <= R);
		}

		inline bool OutofRange(const int L,const int R)
		{
			return (R < l) or (r < L);
		}

		inline void Update()
		{
			Sum = Lson -> Sum + Rson -> Sum;
		}

		inline void MakeTag(const int T)
		{
			Tag += T;
			Sum += (r - l + 1) * T;
		}

		inline void PushDown()
		{
			if(Tag)
			{
				Lson -> MakeTag(Tag);
				Rson -> MakeTag(Tag);
				Tag = 0;
			}
		}

		inline void Modify(const int L,const int R,const int T)
		{
			if(InRange(L,R))
			{
				MakeTag(T);
				return;
			}
			else if(!OutofRange(L,R))
			{
				PushDown();
				Lson -> Modify(L,R,T);
				Rson -> Modify(L,R,T);
				Update();
			}
		}

		inline int GetSum(const int L,const int R)
		{
			if(InRange(L,R)) 
				return Sum;
			if(OutofRange(L,R))
				return 0;
			PushDown();
			return Lson -> GetSum(L,R) + Rson -> GetSum(L,R);
		}

	private:
		int l,r;
		SegmentTree *Lson,*Rson;
		int Sum,Tag;
}*Root;

signed main()
{
	Read_Int(N),Read_Int(M);
	for(int i = 1 ; i <= N ; i ++)
		Read_Int(Array[i]);

	Root = SegmentTree::BuildTree(1,N);

	for(int i = 0,Key,T,L,R ; i < M ; i ++)
	{
		Read_Int(Key),Read_Int(L),Read_Int(R);
		if(Key == 1)
		{
			Read_Int(T);
			Root -> Modify(L,R,T);
		}
		else
			Write_Int(Root -> GetSum(L,R)),putchar('\n');
	}
	return 0;
}
posted @ 2023-09-09 09:03  ZTer  阅读(24)  评论(0编辑  收藏  举报