线段树的一种简单实现
发现之前没有整理过线段树的代码,填一下坑。
下面是洛谷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;
}
繁华尽处,
寻一静谧山谷,
筑一木制小屋,
砌一青石小路,
与你晨钟暮鼓,
安之若素。