zkw 线段树
zkw 线段树
应急时使用。
单点加、区间和
#define lp p<<1
#define rp p<<1|1
int st[MAXN<<2],N=1;
il void bld(int n){
while(N<=n+1) N<<=1;
memcpy(st+N+1,a+1,n<<2);
for(int p=N-1;p;p--) st[p]=st[lp]+st[rp];
}
il void chg(int p,int k){
for(p+=N;p;p>>=1) st[p]+=k;
}
il int ask(int l,int r){
l+=N-1,r+=N+1;
int o=l>>__lg(l^r),L=0,R=0;
while((l>>=__builtin_ctz(~l))!=o) L+=st[++l];
o++;
while((r>>=__builtin_ctz(r))!=o) R+=st[--r];
return L+R;
}
单点修改、区间最值
#define lp p<<1
#define rp p<<1|1
int mx[MAXN<<2],N=1;
il void bld(int n){
while(N<=n+1) N<<=1;
memcpy(mx+N+1,a+1,n<<2);
for(int p=N-1;p;p--) mx[p]=max(mx[lp],mx[rp]);
}
il void chg(int p,ll k){
mx[p+=N]+=k;
k=max(mx[p],mx[p^1]);
for(p>>=1;p;p>>=1) mx[p]=k,k=max(k,mx[p^1]);
}
il int amx(int l,int r){
l+=N-1,r+=N+1;
int o=l>>__lg(l^r),L=0,R=0;
while((l>>=__builtin_ctz(~l))!=o) L=max(L,mx[++l]);
o++;
while((r>>=__builtin_ctz(r))!=o) R=max(R,mx[--r]);
return max(L,R);
}
区间加、区间求和
区间加、区间最值
即得易见平凡,仿照上例显然。留作习题答案略,读者自证不难。
反之亦然同理,推论自然成立。略去过程 $\rm QED$,由上可知证毕。

浙公网安备 33010602011771号