P4315 月下「毛景樹」 邊權改點權問題

2021-10-01 05:08:22 字數 3241 閱讀 1581

//change k w:將第k條樹枝上毛毛果的個數改變為w個。

//cover u v w:將節點u與節點v之間的樹枝上毛毛果的個數都改變為w個。

//add u v w:將節點u與節點v之間的樹枝上毛毛果的個數都增加w個。 由於毛毛蟲很貪,於是他會有如下詢問:

//max u v:詢問節點u與節點v之間樹枝上毛毛果個數最多有多少個。

//這題的重點在兩個標記的同步問題和邊權變點權問題,當改變權值時,要把節點的加的lazy置為0,增加 加的操作時lazy直接加

//pushdown的時候先操作置換的標記再操作加法的標記

//然後是邊權改點權,因為只有n- 1條邊,所以就把邊的權值給兩端深度更低的節點

//再query的時候,其他**不變,只是當詢問的兩個點在同一條重鏈上的時候要將深度低的節點加一,***

#include

using

namespace std;

typedef

long

long ll;

const

int maxn =

1e5+50;

int fa[maxn]

, dep[maxn]

, size[maxn]

, son[maxn]

, top[maxn]

, dfn[maxn]

, rid[maxn]

, cnt =0;

ll val[maxn]

;vector<

int> g[maxn]

;struct node t[maxn *4]

;//第一遍求fa,dep,siz,son陣列

void

dfs1

(int u,

int f)

//fa是父親節點,dep是該節點的深度,size是以該節點為根的大小,son是重兒子}}

//第二遍找出重鏈,求出top陣列

void

dfs2

(int now,

int fir)

//cnt計數器,dfn是dfs序,top是該節點所在重鏈的頭,rid是按dfs序的節點編號

}void

pushup

(int n)

void

pushdown

(int n)

if(t[n]

.lazy)

}void

build

(int n,

int l,

int r)

int mid =

(l + r)

>>1;

build

(n<<

1, l, mid)

;build

(n<<1|

1, mid +

1, r)

;pushup

(n);

}void

update

(int n,

int l,

int r, ll val,

int op)

else

return;}

pushdown

(n);

int mid =

(l + r)

>>1;

if(l <= mid)

update

(n<<

1, l, r, val, op);if

(r > mid)

update

(n<<1|

1, l, r, val, op)

;pushup

(n);

}ll query

(int n,

int l,

int r)

void

subtreechange

(int x,

int val,

int op)

//修改x的所有子樹的權值

ll subtreequery

(int x)

//詢問x的所有子樹的權值和

void

linkchange

(int x,

int y,

int z,

int op)

//修改x和以x為根的子樹的所有節點的權值

if(dep[x]

> dep[y]

)swap

(x, y)

;//重要是加一操作,因為兩個節點之間有差值減一條邊

//深度低的節點代表的邊權不在要求的範圍內

if(dfn[x]+1

<= dfn[y]

)update(1

, dfn[x]+1

, dfn[y]

, z, op)

;//這個判斷操作好像沒有必要,因為按照這個程式進行,條件一定

//滿足,wa的時候再加上吧

}ll linkquery

(int x,

int y)

//詢問從x到y節點的路上的節點權值的和

if(dep[x]

> dep[y]

)swap

(x, y);if

(dfn[x]+1

<= dfn[y]

) ret =

max(ret,

query(1

, dfn[x]+1

, dfn[y]))

;return ret;

}struct linex line[maxn]

;int

main()

dfs1(1

,1);

for(

int i =

1; i <= n -

1; i++

) val[fa[line[i]

.x]== line[i]

.y ? line[i]

.x : line[i]

.y]= line[i]

.z;// for (int i = 1; i <= n; i++)

// printf("\n");

dfs2(1

,0);

build(1

,1, n)

;char s[20]

;while(1

)if(s[1]==

'o')

if(s[1]

=='d')if

(s[1]==

'h')

}return0;

}

P4315 月下「毛景樹」

毛毛蟲經過及時的變形,最終逃過的一劫,離開了菜媽的菜園。毛毛蟲經過千山萬水,歷盡千辛萬苦,最後來到了小小的紹興一中的校園裡。爬啊爬 爬啊爬毛毛蟲爬到了一顆小小的 毛景樹 下面,發現樹上長著他最愛吃的毛毛果 毛景樹 上有n個節點和n 1條樹枝,但節點上是沒有毛毛果的,毛毛果都是長在樹枝上的。但是這棵 ...

題解 P4315 月下「毛景樹」

看原題戳這兒 如題,肯定是樹鏈剖分的題。建議先a掉這道模板題 不會的先看這個 前置知識 鏈式前向星,樹,dfs序,lca,樹形dp,線段樹,樹鏈剖分 一定要先完全學懂,否則不保證這篇題解能完全看懂!先簡化題目 已知一棵包含 n 0 le n le 100000 個結點的樹 連通且無環 每條邊上包含乙...

洛谷P4315 月下「毛景樹」 邊權樹剖 雙標記

題目鏈結 做這道題的時候,乍一看很熟悉,之前考試時也做過類似的題。這道題樹剖 線段樹是個人都看得出來,不過覆蓋標記和加標記同時下放是這道題最坑的地方。當時考試的時候就被這東西搞慘了。做法 樹剖維護邊權的時候等效於維護兩點之間深度較深的點的點權,這很好理解。在修改和查詢的時候,注意到這張圖,我們假定修...