題目如下:
poj 3468
輸入整數n,q,然後輸入n個數的序列,再然後輸入q條詢問,詢問有兩種型別:
q l r 代表列印出區間【l,r】的和
c l r v 代表區間【l,r】區間的數都加v
基本思路:
這裡選擇線段樹,主要是為了練習線段樹標記永久化
下面介紹線段樹標記永久化:
**如下:
#include#include#include#include#include#includeusing namespace std;typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 100000+10;
ll sum[maxn<<2],add[maxn<<2],arr[maxn];
int n,q;
void build(int l,int r,int rt)
int mid=(l+r)/2;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}void update(int l,int r,int val,int l,int r,int rt)
int mid=(l+r)/2;
if(r<=mid)elseelse }}
ll query(int l,int r,ll ad,int l,int r,int rt)
int mid=(l+r)/2;
if(r<=mid)else if(l>mid)else
}int main()
build(1,n,1);
char op[5];
for(int i=1;i<=q;i++)
int mid=(l+r)>>1;
if(xr<=mid) update(rt<<1,l,mid,v,xl,xr);
else
}
詢問時:
由於上面的更新沒有對下面產生影響,所以我們需要一路累加add
'>add
add,直到目前詢問區間與當前區間完全重合的時候,答案為sum
+add
∗'>sum+add∗
sum+add∗區間長度
注意累加add
'>add
add不用累加上完全重合的區間的add
'>add
add,因為它已經在修改的時候對sum
'>sum
sum進行更新了
int query(int rt,int ad,int l,int r,int xl,int xr)int mid=(l+r)>>1;
if(xr<=mid) return query(rt<<1,ad+add[rt],l,mid,xl,xr);
else
}
區間修改線段樹標記永久化模板
#include#include#include#define pos(i,a,b) for(int i=(a);i<=(b);i++)#define n 201000
using namespace std;
int n,m;
int sum[n*4],add[n*4];
int a[n];
void build(int l,int r,int rt)
int mid=(l+r)>>1;
build(l,mid,rt<<1);
build(mid+1,r,rt<<1|1);
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}void update(int rt,int l,int r,int v,int xl,int xr)
int mid=(l+r)>>1;
if(xr<=mid) update(rt<<1,l,mid,v,xl,xr);
else
}int query(int rt,int ad,int l,int r,int xl,int xr)
int mid=(l+r)>>1;
if(xr<=mid) return query(rt<<1,ad+add[rt],l,mid,xl,xr);
else
}int main()
else printf("%d\n",query(1,0,1,n,x,y));
}return 0;
}
線段樹標記永久化
對於樹套樹,主席樹等使用到線段樹的比較複雜的資料結構,如果區間修改的話,打標記後pushdown或者pushup是很難做到的完全不行吧 所以這個時候,乙個神奇的東西誕生了。線段樹標記永久化,維護乙個標記,假設為cov,再維護乙個sum 假設修改區間 ql,qr 全部加上v 和平常一樣,到這個區間後c...
線段樹 標記永久化
一般線段樹做區間修改操作時,先是找到目標區間,然後修改該區間,並打下延遲標記,最後從目標區間自底向上,更新所有包含目標區間的區間的值 即pushup 當該區間子節點被訪問前,pushdown下推標記。這種維護區間的方式存在一點點弊端。例如用這種方式寫一棵可持久化線段樹,因為每次pushdown都相當...
線段樹 永久化標記優化
誕生 正常的線段樹的改段求段都離不開lazy標記,lazy標記維護時要及時的更新,即人們熟知的pushdown函式。那麼能不能避免這麼多次無意義的pushdown操作呢?他就是 標記永久化。原理 舉個最簡單的例子,線段樹區間修改,求區間最大值。這時的lazy存的是當前這一段待下傳的最大值,也就是說這...