线段树模板(待补完)
因为每次写线段树都要纠结好久...于是决定将成型的模板放在这里 以后直接打上去就好了=-=
建树:
tips1:初值都是0可以省略
tips2:对于不同的维护值要用不同的标记
void build(ll l,ll r,ll pos) { if(l==r) { tr[pos].w=a[l]; return ; } ll mid=l+r>>1; build(l,mid,pos<<1); build(mid+1,r,pos<<1|1); tr[pos].w=tr[pos<<1].w+tr[pos<<1|1].w; }
单点查询:
ll ask(ll l,ll r,ll pos,ll x) { if(l==r) { return tr[pos].w; } if(tr[pos].f)down(pos); ll mid=l+r>>1; if(mid>=x)return ask(l,mid,pos<<1,x); else return ask(mid+1,r,pos<<1|1,x); }
区间加:
void add(ll l,ll r,ll pos,ll a,ll b,ll x) { if(l>=a&&r<=b) { tr[pos].w+=x; tr[pos].f+=x; return ; } ll mid=l+r>>1; if(tr[pos].f)down(pos); if(b<=mid) add(l,mid,pos<<1,a,b,x); else if(a>mid) add(mid+1,r,pos<<1|1,a,b,x); else add(l,mid,pos<<1,a,b,x),add(mid+1,r,pos<<1|1,a,b,x); tr[pos].w=tr[pos<<1].w+tr[pos<<1|1].w; }
打标记:
void down(ll pos) { ll x=tr[pos].f; tr[pos<<1].f+=x; tr[pos<<1|1].f+=x; tr[pos].f=0; }
就让我永远不在这里写下什么有意义的话——by 吉林神犇 alone_wolf