1. 程式人生 > >[Luogu P4719] 【模板】動態dp

[Luogu P4719] 【模板】動態dp

洛谷傳送門

題目描述

給定一棵 n n 個點的樹,點帶點權。

m m 次操作,每次操作給定 x ,

y x,y ,表示修改點 x x 的權值為 y y

你需要在每次操作之後求出這棵樹的最大權獨立集的權值大小。

輸入輸出格式

輸入格式:

第一行, n , m n,m ,分別代表點數和運算元。

第二行, V 1

, V 2 , . . . , V n V_1,V_2,...,V_n ,代表 n n 個點的權值。

接下來 n 1 n-1 行, x , y x,y ,描述這棵樹的 n 1 n-1 條邊。

接下來 m m 行, x , y x,y ,修改點 x x 的權值為 y y

對於每個操作輸出一行一個整數,代表這次操作後的樹上最大權獨立集。

保證答案在 i n t int 範圍內

輸入輸出樣例

輸入樣例#1:

10 10
-11 80 -99 -76 56 38 92 -51 -34 47 
2 1
3 1
4 3
5 2
6 2
7 1
8 2
9 4
10 7
9 -44
2 -17
2 98
7 -58
8 48
3 99
8 -61
9 76
9 14
10 93

輸出樣例#1:

186
186
190
145
189
288
244
320
258
304

說明

對於 30 % 30\% 的資料, 1 n , m 10 1\le n,m\le 10

對於 60 % 60\% 的資料, 1 n , m 1000 1\le n,m\le 1000

對於 100 % 100\% 的資料, 1 n , m 1 0 5 1\le n,m\le 10^5

解題分析

noip之前瞄了一眼這個玩意, 覺得太毒瘤了就沒有細看, 然後居然考了QAQ…

如果不修改的話就是一個 S B 0 / 1 D P SB0/1DP 。 然而如果加上了修改一下就變得毒瘤起來。

這裡有一種很神奇的做法:將整顆樹先進行樹鏈剖分, 然後對於重鏈上的每個點, 維護其輕兒子上的資訊, 再結合重鏈向上遞推。

具體而言, 設 d p [ i ] [ 1 / 0 ] dp[i][1/0] 表示 D F S DFS 序為 i i 節點選與不選的子樹的最優解, g [ i ] [ 1 / 0 ] g[i][1/0] 表示選與不選虛兒子的貢獻, s o n [ i ] son[i] 表示 i i 的重兒子, 那麼就有:
g [ i ] [ 0 ] = E d g e ( i , j ) , j s o n [ i ] m a x ( d p [ j ] [ 0 ] , d p [ j ] [ 1 ] ) g [ i ] [ 1 ] = E d g e ( i , j ) , j s o n [ i ] d p [ j ] [ 0 ] + v a l [ i ] d p [ i ] [ 0 ] = g [ i ] [ 0 ] + m a x ( d p [ s o n [ i ] ] [ 0 ] , d p [ s o n [ i ] ] [ 1 ] ) d p [ i ] [ 1 ] = g [ i ] [ 1 ] + d p [ s o n [ i ] [ 0 ] ] g[i][0]=\sum_{Edge(i,j),j\ne son[i]} max(dp[j][0],dp[j][1]) \\ g[i][1] =\sum_{Edge(i,j),j\ne son[i]}dp[j][0] +val[i] \\ dp[i][0]=g[i][0]+max(dp[son[i]][0],dp[son[i]][1]) \\ dp[i][1]=g[i][1]+dp[son[i][0]]
然後我們把矩陣乘法魔改一下, 把原來的乘法換成加法, 把原來的加法換成取 m a x max , 因為乘法和加法之間滿足分配率, 加法滿足交換律, 而加法和 m a x max 之間也滿足分配率, m a x max 滿足交換律, 不難發現它們的關係是等價的, 所以改編出的矩乘也是滿足結合律的。

構造出來的矩陣大概是這個樣子的:

[ g [ i ] [ 0 ] g [ i ] [ 0 ] g [ i ] [ 1 ] I N F ] × [ d p [ s o n [ i ] ] [ 0 ] d p [ s o n [ i ] ] [ 1 ] ] = [ d p [ i ] [ 0 ] d p [ i ] [ 1 ] ] \left[ \begin{matrix} g[i][0] & g[i][0]\\ g[i][1] & -INF \end{matrix} \right] \times \left[ \begin{matrix} dp[son[i]][0]\\ dp[son[i]][1] \end{matrix} \right] = \left[ \begin{matrix} dp[i][0]\\ dp[i][1] \end{matrix} \right]
然後我們發現似乎對於一個重鏈末端的點, 第二個矩陣就是單位矩陣, 所以直接維護第一個矩陣的乘積就可以得到一個非末端的點的 d p dp 值。 換句話說, 對於重鏈上編號為 i , i + 1 , . . . , j i,i+1,...,j j j 是末端)的一部分, d p [ i ] dp[i] 可以通過這個字尾連乘積得到。

所以我們就可以用線段樹維護區間矩陣乘積, 每次修改的時候單點修改到對應點的

相關推薦

luogu P4719 模板動態dp

update tdi bsp int -s mil scan () 通過 noip怎麽考這種東西啊。。。看錯題場上爆零涼了 首先我們先進行樹鏈剖分,那麽問題可以轉換成重鏈的答案+其他子節點的答案 而每次修改相當於改一段重鏈的答案,改一次其他子節點的答案交替進行 這樣只

[Luogu P4719] 模板動態dp

洛谷傳送門 題目描述 給定一棵 n n n個點的樹,點帶點權。 有

P4719 模板動態dp

P4719 【模板】動態dp 神仙東西orz 動態dp簡單來說就是dp可以用矩陣來轉移,用LCT來維護矩陣的轉移。 那麼簡單來說就是pj難度的DP,tg難度的矩乘,以及noip+難度的LCT。 pj難度dp:設\(dp[i][j]\)表示點i不選/選。\(f[x][0]=\sum f[son][1

洛谷 P4719 模板動態dp動態dp

是動態dp的板子 大致思想就是用g[u]來表示不包含重鏈轉移的dp值,然後用線段樹維護重鏈,這樣線段樹的根就相當於這條重鏈的top的真實dp值 每次修改的時候,修改x點會影響到x到根的真實dp值,但是隻會影響到每條重鏈的低端點的dp值,相當於在log個線段樹上單點修改 #include<iostrea

Luogu P4643 模板動態dp(矩陣乘法,線段樹,樹鏈剖分)

題面 給定一棵 \(n\) 個點的樹,點帶點權。 有 \(m\) 次操作,每次操作給定 \(x,y\) ,表示修改點 \(x\) 的權值為 \(y\) 。 你需要在每次操作之後求出這棵樹的最大權獨立集的權值大小。 題解 如題所示 , 是個模板題 ... 首先考慮靜態 \(dp\) , 令 \(dp_{u,

LG4719 模板動態dp

統一 char log gis matrix www reg query eof 題意 題目描述 給定一棵\(n\)個點的樹,點帶點權。 有\(m\)次操作,每次操作給定\(x,y\),表示修改點\(x\)的權值為\(y\)。 你需要在每次操作之後求出這棵樹的最大權獨立集的

luogu P3690 模板Link Cut Tree (動態樹)

clu pda col make class getchar() root 動態樹 pan https://www.luogu.org/problemnew/show/3690 這大概還是一道模板題目 #include<cstdio> #include

Luogu P3375 模板KMP字符串匹配

ogr oss tel 詳解 最長 arch tro long abc P3375 【模板】KMP字符串匹配 題目描述 如題,給出兩個字符串s1和s2,其中s2為s1的子串,求出s2在s1中所有出現的位置。 為了減少騙分的情況,接下來還要輸出子串的前綴數組

luogu P3368 模板樹狀數組 2

進行 print sin spa 初始 nbsp 增加 樹狀 () P3368 【模板】樹狀數組 2 題目描述 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數數加上x 2.求出某一個數的和 輸入輸出格式 輸入格式: 第一行包含兩個整數

原創洛谷 LUOGU P3373 模板線段樹2

取模 file 需要 code ace highlight dig org zh-cn P3373 【模板】線段樹 2 題目描述 如題,已知一個數列,你需要進行下面兩種操作: 1.將某區間每一個數加上x 2.將某區間每一個數乘上x 3.求出

紅黑樹 ------ luogu P3369 模板普通平衡樹(Treap/SBT)

div child lin main false tchar clas char als 二次聯通門 : luogu P3369 【模板】普通平衡樹(Treap/SBT) 近幾天閑來無事。。。就把各種平衡樹都寫了一下。。。 下面是紅黑樹(Red Black Tree)

替罪羊樹 ------ luogu P3369 模板普通平衡樹(Treap/SBT)

nod %d clas https number problem 普通 true ble 二次聯通門 : luogu P3369 【模板】普通平衡樹(Treap/SBT) 閑的沒事,把各種平衡樹都寫寫 比較比較。。。 下面是替罪羊樹 #include &l

數組splay ------ luogu P3369 模板普通平衡樹(Treap/SBT)

普通 模板 char truct div color fine col suffix 二次聯通門 : luogu P3369 【模板】普通平衡樹(Treap/SBT) #include <cstdio> #define Max 100005

luogu P3809 模板後綴排序

二次 [] == suffix fix turn read max reg 二次聯通門 : luogu P3809 【模板】後綴排序 /* luogu P3809 【模板】後綴排序 後綴數組 sa表示 排名為i的是第幾

luogu P3370 模板字符串哈希

pro href 給定 ring std namespace 興趣 scanf clu 題目描述 如題,給定N個字符串(第i個字符串長度為Mi,字符串內包含數字、大小寫字母,大小寫敏感),請求出N個字符串中共有多少個不同的字符串。 友情提醒:如果真的想好好練習哈希

luogu P3388 模板割點(割頂)

true algorithm fin can clas light fine sca 表示 題目背景 割點 題目描述 給出一個n個點,m條邊的無向圖,求圖的割點。 輸入輸出格式 輸入格式: 第一行輸入n,m 下面m行每行輸

fhq treap ------ luogu P3369 模板普通平衡樹(Treap/SBT)

ret true read std stdin urn tdi ref code 二次聯通門 : LibreOJ #104. 普通平衡樹 #include <cstdio> #include <iostream> #include

Luogu P3378 模板

題目 最小 color nbsp adl 數據 描述 https 包含 題目描述 如題,初始小根堆為空,我們需要支持以下3種操作: 操作1: 1 x 表示將x插入到堆中 操作2: 2 輸出該小根堆內的最小數 操作3: 3 刪除該小根堆內的最小數 輸入輸出格式 輸入格式: 第

[Luogu 3919]模板可持久化數組(可持久化線段樹/平衡樹)

ins eset blog sta -s ctime it is put tex Description 如題,你需要維護這樣的一個長度為 N 的數組,支持如下幾種操作 在某個歷史版本上修改某一個位置上的值 訪問某個歷史版本上的某一位置的值 此外,每