差分 樹上差分略解

2021-09-10 09:35:25 字數 3630 閱讀 4545

差分、樹上差分略解

哈哈差分?  

先來看一道題:  

題目描述:   

–給定包含 n個數的陣列 a1,a2,…,an.有 k次操作 每次操作把區間[l,r]加上v

。最後求出數列每個位置的數。     

輸入格式  

–第一行,n.第二行,a1,a2,…,an下一行,k,下k行,每行乙個操作,格式為l,r,v  

輸出格式  

–一行,更新後的陣列   

樣例輸入  

5  1 2 3 4 5  

3  1 5 1 

2 4 3  

5 5 2  

樣例輸出  

2 6 7 8 8   

資料規模  

10%,n≤5,k≤5  

30%,n≤103,k≤103       

另20%,n≤105,k≤105,l=r     

另30%,n≤105,k≤105,v=1     

100%,n≤5∗105,k≤105    

思路   

…   

線段樹? 

樹狀陣列?  

各種資料結構?   

如果這題是o(n)的呢?

所以…   

差分是啥?  

差分可以簡單理解為前乙個數與後乙個數的差值。  

每次修改只將頭和尾的差分值改一改就可以了  

十分好理解  

看上面jloi的例題   

線段樹/樹狀陣列**:(感謝lhy)

#include

using

namespace std;

long

long a[

600007

],c[

600007];

long

long n;

long

long

lowbit

(long

long x)

void

add(

int p,

int x)

void

range_add

(int l,

int r,

int x)

intsum

(int p)

intmain()

cin>>k;

for(

int i=

1;i<=k;i++

)for

(int i=

1;i<=n;i++

)}

正解(差分):

#include

using

namespace std;

const

int n=

500005

;typedef

long

long ll;

ll a[n]

;int n;

int k;

ll hx;

ll q[n]

;int

main()

q[0]=a[1]

;for

(int i=

1;i<=n;i++

)scanf

("%d"

,&k)

;for

(int i=

1;i<=k;i++

)for

(int i=

1;i<=n;i++

)printf

("\n");

return0;

}

所以。。。more例題!   

例題:借教室!

#include

using

namespace std;

const

int n=

1000005

;struct nodes[n]

;int n,m;

int d[n]

;int l=

1,r;

int ans=-1

;int k[n]

;bool

check

(int u)

int p=0;

for(

int i=

1;i<=n;i++

)return1;

}int

main()

r=m;

while

(l<=r)

printf

("-1\n%d\n"

,l);

return0;

}

名字很高大上   

但是…還行   

就是對一棵樹上x->y的路徑所有數+1   

此類問題:  

cnt[a]++   

cnt[b]++  

cnt[lca]--   

cnt[father[lca]]--   

最後dfs一遍   

就可以了!  

例題: 

例題:最大流!

裸的模板…

#include

using

namespace std;

#define re register

const

int maxn=

50010

;int n,m;

int hed[maxn<<2]

,tal[maxn<<2]

,nxt[maxn<<2]

,cnt=0;

int root;

int s[maxn]=;

int rt;

int dfn[maxn]=;

int f[maxn][30

];int power[30]

;int ans=0;

void

addege

(int x,

int y)

intlca

(int x,

int y)}}

if(x==y)

return x;

re int p;

for(p=

20;p>=

0;p--)}

return f[x][0

];}void

dfs(

int x,

int flow,

int father)

}void

init()

}void

dfs(

int x,

int father)

if(s[x]

>ans) ans=s[x];}

intmain()

rt=1;

dfs(rt,0,

0);memset

(s,0

,sizeof

(s))

;for

(re int i=

1;i<=m;i++

)//cout << s[4] << endl;

dfs(rt,0)

;printf

("%d\n"

,ans)

;return0;

}

差分總結二 樹上差分

找這個樹上 重複經過的最多點 經過幾次 看這名字 就醉了orz 這題是 樹上差分 模板題 點差分 點差分的話 由於 lca 本身是有貢獻的 那麼d lca 用d lca父親 只要消掉影響 include using namespace std const int maxn 1e5 10 int n,...

樹上差分的整理(點的樹上差分和邊的樹上差分)

點的樹上差分 若經過 u 到 v 的所有點,tmp u tmp v tmp lca u,v tmp parent lca u,v 0 例題 include using namespace std struct ss ss data 600010 int n,q int a 300010 head 6...

字首和 差分與樹上差分

1.1 字首和 字首和可以通過對乙個序列進行o n 的預處理後,在o 1 時間內求出任意乙個子串行的和。1.2 差分 可以用於求解多次區間修改與區間詢問的題型,例如多次次給 l r 內所有數 val,就可以用差分以及字首和來優化。區間操作o 1 區間詢問o n 處理,o 1 查詢。1.3 樹上差分 ...