[模板]基本線段樹操作
阿新 • • 發佈:2018-12-13
嗑兩天的線段樹,終於tm學會了
結構體構造
struct Node { int l,r; int w,tag; }Tree[4*N+1];
建樹
void build(int p,int l,int r) { Tree[p].l=l; Tree[p].r=r; if(l==r){ Tree[p].w=A[l]; return; } int mid=(l+r)>>1; build(lson(p),l,mid); build(rson(p),mid+1,r); Tree[p].w=Tree[lson(p)].w+Tree[rson(p)].w; return; }
下傳延遲標記
void add(int p,int l,int r,int k) { Tree[p].w+=(r-l+1)*k; Tree[p].tag+=k; return; } void down(int p,int l,int r) { if(!Tree[p].tag)return; int mid=(l+r)>>1; add(lson(p),l,mid,Tree[p].tag); add(rson(p),mid+1,r,Tree[p].tag); Tree[p].tag=0; return; }
區間加法
void modify(int p,int x,int y,int l,int r,ll k) { if(y<l||x>r)return; if(x<=l&&r<=y){ Tree[p].w+=k*(r-l+1); Tree[p].tag+=k; return; } down(p,l,r); int mid=(l+r)>>1; if(x<=mid)modify(lson(p),x,y,l,mid,k); if(y>mid)modify(rson(p),x,y,mid+1,r,k); Tree[p].w=Tree[lson(p)].w+Tree[rson(p)].w; return; }
區間詢問和
int query(int p,int l,int r,int x,int y) { if(y<l||x>r)return 0; if(x<=l&&r<=y)return Tree[p].w; down(p,l,r); int mid=(l+r)>>1; int res=0; if(x<=mid)res+=query(lson(p),l,mid,x,y); if(y>mid)res+=query(rson(p),mid+1,r,x,y); return res; }