zkw线段树

来源:互联网 发布:吾爱免流流控源码 编辑:程序博客网 时间:2024/05/21 09:16

zkw线段树是一种不需要递归的线段树,而且代码比较简便。
不需要递归主要用的方法是利用父亲与儿子的下标的关系,比如说对于节点i,其父节点为i>>1,左儿子节点为i<<1,右儿子为i>>1|1,所以其实仔细分析普通线段树的时候,会发现有时候确实不需要递归。

性质和普通的线段树差不多,现在本人还没有试过在zkw上打惰性标记,也不知道可不可以,能打出来就马上改。

下面的代码给出的是比较多的操作,函数名英文差不多代表了函数的作用,便于理解

#include<cstdio>#include<algorithm>using namespace std;const int MAXN = 100000;int n,M,m;int d[MAXN<<1];int Read();void Build();void Query_OnePoint_Build();int Query_OnePoint_Sum(int);void Maintain_Max();void Maintain_Min();void Maintain_Sum();void Change(int,int);int Get_Sum(int,int);int Get_Max(int,int);int Get_Min(int,int);void Add(int,int,int);int main(){    return 0;}int Read(){    int in=0,f=1;    char ch=getchar();    for(;ch>'9'||ch<'0';ch=getchar()) if(ch=='-') f=-1;    for(;ch>='0'&&ch<='9';ch=getchar()) in=in*10+ch-'0';    return in*f;}void Build(){    for(M=1;M<n+2;M<<=1);    for(int i=M+1;i<=M+n;i++) d[i]=Read();}void Query_OnePoint_Build(){    for(M=1;M<n+2;M<<=1);for(int i=M+1;i<=M+n;i++) d[i]=Read();    for(int i=M-1;i;i--) d[i]=min(d[i<<1],d[i<<1|1]),d[i<<1]-=d[i],d[i<<1|1]-=d[i];}int Query_OnePoint_Sum(int x){    int Ans=0;    while(x) Ans+=d[x],x>>=1;    return Ans;}void Maintain_Max(){    for(int i=M-1;i;i--) d[i]=max(d[i<<1],d[i<<1|1]);}void Maintain_Min(){    for(int i=M-1;i;i--) d[i]=min(d[i<<1],d[i<<1|1]);}void Maintain_Sum(){    for(int i=M-1;i;i--) d[i]=d[i<<1]+d[i<<1|1];}void Change(int x,int k){    for(d[x+=M]+=k,x>>=1;x;x>>=1)        d[x]=d[x<<1]+d[x<<1|1];}int Get_Sum(int s,int t){    int Ans=0;    for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){        if(~s&1) Ans+=d[s^1];        if( t&1) Ans+=d[t^1];    }    return Ans;}int Get_Max(int s,int t){    int L=0,R=0;    for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){        L+=d[s];R+=d[t];        if(~s&1) L=max(L,d[s^1]);        if( t&1) R=max(R,d[t^1]);    }    int Ans=max(L,R);while(s) Ans+=d[s>>=1];    return Ans;}int Get_Min(int s,int t){    int L=0,R=0;    for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){        L+=d[s];R+=d[t];        if(~s&1) L=min(L,d[s^1]);        if( t&1) R=min(R,d[t^1]);    }    int Ans=min(L,R);while(s) Ans+=d[s>>=1];    return Ans;}void Add(int s,int t,int k){    int A=0;    for(s+=M-1,t+=M+1;s^t^1;s>>=1,t>>=1){        if(~s&1) d[s^1]+=k; if(t&1) d[t^1]+=k;        A=min(d[s],d[s^1]);d[s]-=A;d[s^1]-=A;d[s>>1]+=A;        A=min(d[t],d[t^1]);d[t]-=A;d[t&1]-=A;d[t>>1]+=A;    }    while(s) A=min(d[s],d[s^1]),d[s]-=A,d[s^1]-=A,d[s>>=1]+=A;}
0 0
原创粉丝点击