線段樹的單點修改加區間修改
阿新 • • 發佈:2019-02-17
const int maxn=1e6+5; int a[maxn]; //存每個數的值 struct node { int sum; int ll,rr; }tree[maxn*4]; void Pushup(int id) //區間合併 { tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; } void Pushdown() //區間下放,進行區間修改的時候用到 { } void Build(int id,int ll,int rr) //建樹 { tree[id].ll=ll; tree[id].rr=rr; if(ll==rr) { tree[id].sum=a[ll]; return; } int mid=(ll+rr)/2; //mid=ll+rr>>1; Build(id*2,ll,mid); Build(id*2+1,mid+1,rr); //Build(id<<1,ll,mid); //Build(id<<1|1,mid+1,rr); Pushup(id); } void Update(int id,int x,int y) //修改 { if(tree[id].ll==tree[id].rr) { tree[id].sum=y; return; } int mid=(tree[id].ll+tree[id].rr)/2; if(x<=mid) Update(id*2,x,y); else Update(id*2+1,x,y); Pushup(id); } int Query(int id,int x,int y) //查詢 { if(x<=tree[id].ll&&tree[id].rr<=y)//到頭的情況 return tree[id].sum; int mid=(tree[id].ll+tree[id].rr)/2; if(y<=mid) //只需要訪問左邊 return Query(id*2,x,y); else if(x>=mid+1) return Query(id*2+1,x,y); else return Query(id*2,x,y)+Query(id*2+1,x,y); }
const int maxn=1e6+5; long long int a[maxn]; long long int lazy[maxn*4]; //存每個數的值 struct node { long long int sum; long long int ll,rr; }tree[maxn*4]; void Pushup(int id) //區間合併 { tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; } void Pushdown(int id) //區間下放,進行區間修改的時候用到 { if(lazy[id]) { tree[id*2].sum+=lazy[id]*(tree[id*2].rr-tree[id*2].ll+1); tree[id*2+1].sum+=lazy[id]*(tree[id*2+1].rr-tree[id*2+1].ll+1); lazy[id*2]+=lazy[id]; lazy[id*2+1]+=lazy[id]; lazy[id]=0; } } void Build(int id,int ll,int rr) //建樹 { lazy[id]=0; tree[id].ll=ll; tree[id].rr=rr; if(ll==rr) { tree[id].sum=a[ll]; return; } int mid=(ll+rr)/2; //mid=ll+rr>>1; //Build(ltree); //Build(rtree); Build(id<<1,ll,mid); Build(id<<1|1,mid+1,rr); Pushup(id); } void Update(int id,int x,int y,int z) //修改 { if(x<=tree[id].ll&&tree[id].rr<=y) { tree[id].sum+=z*(tree[id].rr-tree[id].ll+1); lazy[id]+=z; return; } int mid=(tree[id].ll+tree[id].rr)/2; Pushdown(id); if(y<=mid) Update(id*2,x,y,z); else if(x>=mid+1) Update(id*2+1,x,y,z); else { Update(id*2,x,y,z); Update(id*2+1,x,y,z); } Pushup(id); } long long int Query(int id,int x,int y) //查詢 { if(x<=tree[id].ll&&tree[id].rr<=y)//到頭的情況 return tree[id].sum; int mid=(tree[id].ll+tree[id].rr)/2; Pushdown(id); if(y<=mid) //只需要訪問左邊 return Query(id*2,x,y); else if(x>=mid+1) return Query(id*2+1,x,y); else return Query(id*2,x,y)+Query(id*2+1,x,y); }