参考博客:
线段树:是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。
使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,实际应用时一般还要开4N的数组以免越界,因此有时需要离散化让空间压缩。
struct node
{
long long sum,l,r,tag;
}t[666666];
long long num[666666];
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
if(l==r)
{
t[p].sum=num[l];
return ;
}
int mid=(l+r)/2;
build(2*p,l,mid);
build(2*p+1,mid+1,r);
t[p].sum=t[2*p].sum+t[2*p+1].sum;
}
void lazy(int p)
{
if(t[p].tag)
{
t[2*p].sum+=t[p].tag*(t[p*2].r-t[p*2].l+1);
t[2*p+1].sum+=t[p].tag*(t[p*2+1].r-t[p*2+1].l+1);
t[2*p].tag+=t[p].tag;
t[2*p+1].tag+=t[p].tag;
t[p].tag=0;
}
}
void change(int p,int x,int y,int z)
{
if(t[p].l>=x&&t[p].r<=y)
{
t[p].sum+=1LL*z*(t[p].r-t[p].l+1);
t[p].tag+=z;
return ;
}
int mid=(t[p].l+t[p].r)/2;
lazy(p);
if(x<=mid)
{
change(p*2,x,y,z);
}
if(y>mid)
{
change(p*2+1,x,y,z);
}
t[p].sum=t[2*p].sum+t[p*2+1].sum;
return ;
}
long long sum(int p,int x,int y)
{
if(t[p].l>=x&&t[p].r<=y)
{
return t[p].sum;
}
int mid=(t[p].l+t[p].r)/2;
long long ans=0;
lazy(p);
if(x<=mid)
{
ans+=sum(p*2,x,y);
}
if(mid<y)
{
ans+=sum(p*2+1,x,y);
}
return ans;
}
long long single_sum(int p,int x)
{
{
if(t[p].l==t[p].r&&t[p].l==x)
{
return t[p].sum;
}
int mid=(t[p].l+t[p].r)/2;
lazy(p);
long long ans=0;
if(mid>=x)
{
ans+=single_sum(2*p,x);
}
if(mid<x)
{
ans+=single_sum(2*p+1,x);
}
return ans;
}
}
void single_change (int p,int x,int z)
{
if(t[p].l==t[p].r&&t[p].l==x)
{
t[p].sum+=z;
return ;
}
int mid=(t[p].l+t[p].r)/2;
if(mid>=x)
{
single_change(2*p,x,z);
}
if(mid<x)
{
single_change(2*p+1,x,z);
}
t[p].sum=t[p*2].sum+t[p*2+1].sum;
}
void lazy(int p)
{
if(t[p].tag)
{
t[2*p].sum=t[p].tag*(t[p*2].r-t[p*2].l+1);//少了一个+号
t[2*p+1].sum=t[p].tag*(t[p*2+1].r-t[p*2+1].l+1);//少了一个+号
t[2*p].tag=t[p].tag;
t[2*p+1].tag=t[p].tag;
t[p].tag=0;
}
}
void change(int p,int x,int y,int z)
{
if(t[p].l>=x&&t[p].r<=y)
{
t[p].sum=1LL*z*(t[p].r-t[p].l+1);//少了一个+号
t[p].tag=z;
return ;
}
int mid=(t[p].l+t[p].r)/2;
lazy(p);
if(x<=mid)
{
change(p*2,x,y,z);
}
if(y>mid)
{
change(p*2+1,x,y,z);
}
t[p].sum=t[2*p].sum+t[p*2+1].sum;
return ;
}
const int maxn = 200000+200;
struct node
{
int l,r,maxx,minn;
}t[maxn<<2];
int num[maxn];
void build(int p,int l,int r)
{
t[p].l=l;
t[p].r=r;
if(l==r)
{
t[p].maxx=num[l];
t[p].minn=num[l];
return ;
}
int mid=(l+r)>>1;
build(p<<1,l,mid);
build(p<<1|1,mid+1,r);
t[p].maxx=max(t[p<<1].maxx,t[p<<1|1].maxx);
t[p].minn=min(t[p<<1].minn,t[p<<1|1].minn);
}
int search_max(int pos,int x,int y)
{
if(x<=t[pos].l&&y>=t[pos].r)
{
return t[pos].maxx;
}
int ans=-1;
int mid=(t[pos].l+t[pos].r)>>1;
if(x<=mid) ans=max(ans,search_max(pos<<1,x,y));
if(y>mid) ans=max(ans,search_max(pos<<1|1,x,y));
return ans;
}
int search_min(int pos,int x,int y)
{
if(x<=t[pos].l&&y>=t[pos].r)
{
return t[pos].minn;
}
int ans=10000000+1;
int mid=(t[pos].l+t[pos].r)>>1;
if(x<=mid) ans=min(ans,search_min(pos<<1,x,y));
if(y>mid) ans=min(ans,search_min(pos<<1|1,x,y));
return ans;
}