線段樹(1)
阿新 • • 發佈:2021-07-28
線段樹(1)
最基礎的模板:
#define ls(x) x<<1 #define rs(x) x<<1|1 ll tree[N<<2],tag[N<<2]; ll a[N]; void up(ll p){ tree[p] = tree[ls(p)]+tree[rs(p)]; } //建樹 void build(ll p,ll pl,ll pr){ if(pl == pr) { tree[p] = a[pl]; return; } ll mid = (pl+pr)>>1; build(ls(p),pl,mid); build(rs(p),mid+1,pr); up(p); } void add(ll p,ll pl,ll pr,ll d){ tag[p] += d; tree[p] += d*(pr-pl+1); } void push_down(ll p,ll pl,ll pr){ if(tag[p]){ ll mid = (pl+pr)>>1; add(ls(p),pl,mid,tag[p]); add(rs(p),mid+1,pr,tag[p]); tag[p] = 0; } } void update(ll L,ll R,ll p,ll pl,ll pr,ll d){ if(L <= pl && pr <= R){ add(p,pl,pr,d); return; } push_down(p,pl,pr); ll mid = (pl+pr)>>1; if(L <= mid) update(L,R,p,pl,mid,d); if(mid < R) update(L,R,p,mid+1,d); up(p,pl,pr); } ll query(ll L,ll R,ll p,ll pl,ll pr){ if(L <= pl && pr <= R){ return tree[p]; } push_down(p,pl,pr); ll mid = (pl+pr)>>1; ll res = 0; if(L <= mid) res += query(L,R,ls(p),pl,mid); if(mid < R) res += query(L,R,rs(p),mid+1,R); return res; }