zwk线段树,即非递归的线段树。
优点:常数小,代码短。
缺点:貌似不太好处理区间修改的操作。
代码:
//建树 inline void Build(int n){ for(M=1;M<n;M<<=1);//找到M for(int i=M+1;i<=M+n;i++)cin>>d[i];//输入 for(int i=M-1;i;i--)d[i]=d[i<<1]+d[i<<1|1];//建树 } //单点修改 inline void change(int pos,int v){ for(int i=(M+pos);i;i>>=1)d[i]+=v; } //区间查询 inline int sum(int l,int r,int res=0){ for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1){ if(~l&1) res+=d[l^1]; if( r&1) res+=d[r^1]; } return res; }
//建树 inline void Build(long long n){ for(M=1;M<n;M<<=1); for(long long i=M+1;i<=M+n;i++)cin>>d[i]; for(long long i=M-1;i;i--)d[i]=d[i<<1]+d[i<<1|1]; } //单点修改 inline void change(long long pos,long long x){ for(long long i=M+pos;i;i>>=1)d[i]+=x; } //区间修改 inline void change_intrval(long long l,long long r,long long c){ long long lnum=0,rnum=0,nnum=1; for(l=M+l-1,r=M+r+1;l^r^1;l>>=1,r>>=1,nnum<<=1){ d[l]+=c*lnum; d[r]+=c*rnum; if(~l&1) {lazy[l^1]+=c;d[l^1]+=c*nnum;lnum+=nnum;} if( r&1) {lazy[r^1]+=c;d[r^1]+=c*nnum;rnum+=nnum;} } for(;l;l >>=1,r>>=1){ d[l]+=c*lnum; d[r]+=c*rnum; } } //区间查询 inline long long GetSum(long long l,long long r,long long res=0){ long long lnum=0,rnum=0,nnum=1; for(l=l+M-1,r=r+M+1;l^r^1;l>>=1,r>>=1,nnum <<=1){ res +=lazy[l]*lnum; res +=lazy[r]*rnum; if(~l&1) {res+=d[l^1];lnum +=nnum;} if( r&1) {res+=d[r^1];rnum +=nnum;} } for(;l;l >>=1,r>>=1){ res +=lazy[l]*lnum; res +=lazy[r]*rnum; } return res; }