小奇的倉庫 換根dp

2022-02-18 16:14:38 字數 1586 閱讀 7576

一道很好的換根dp題。考場上現場yy十分愉快

給定樹,求每個點的到其它所有點的距離異或上m之後的值,n=100000,m<=16

只能線性複雜度求解,m又小得奇怪。或者帶乙個log像kx一樣打乙個線段樹

我們可以發現,m小的話對距離很大的路徑的影響也不會超過16。

那麼變化的其實就是最後4個二進位制位啊。

所以我們像普通的換根dp一樣求出所有距離,在額外處理一下以p為端點的全部路徑裡路徑長度%16之後的值為k的有多少個

設為bits2[k][p]

因為換根dp的主要思路是兩遍dfs,第一次處理每個點的子樹,第二遍處理以這個點為端點的所有點對的狀態

設子樹里所有的點到當前根節點的距離是dt[p],子樹所有點到當前根節點的路徑%16之後值為k的路徑有k個設為bits[k][p]

那麼第一輪dfs轉移還是很顯然的,我稍微說一下第二輪。

dt[p]=dt[p]+dt[f[p]]-(dt[p]+siz[p]*vtf[p])+vtf[p]*(n-siz[p]);其中vtf[p]表示p節點到其父親的距離

=p的子樹裡所有點到p的距離+所有點到p的父親的距離-(p子樹內的點到p的距離+這些點從p再到p父親的距離)+子樹p外的所有點從p父親到p的距離

兩個公式的每個部分都是對應的

那麼bits陣列的轉移也是大同小異了(雖說稍複雜一些)

for(int j=0;j<=15;++j) bits2[j+vtf[p]&15][p]=bits[j+vtf[p]&15][p]+bits2[j][f[p]]-bits[j-vtf[p]+16&15

][p];

首先是子樹里本身就有bits[j+vtf[p]&15

]個點滿足條件

到父親的距離為j的所有點裡去除子樹p裡的貢獻就是bits2[j][f[p]]-bits[j-vtf[p]+16&15][p]

自己想?

容易重複考慮自己到自己的距離為0而異或後不是0的情況,要減去m

1

//這個異或是個狗屎啊!!!但是其實異或的二進位制位也不超過4,特殊處理一下?2//

對於每乙個節點計算出子樹所有點到它的距離和,再計算出有多少點到它的距離&15後是幾

3 #include4

#define int long long

5int n,m,cnt,fir[100005],l[200005],to[200005],v[200005],dt[100005],siz[100005];6

int bits[16][100005],f[100005],vtf[100005],bits2[16][100005];7

void dfs(int p,int

fa)13}14

void dfs(int

p)else

for(int j=0;j<=15;++j)bits2[j][1]=bits[j][1

];19

for(int i=fir[p];i;i=l[i]) if(to[i]!=f[p]) dfs(to[i]);20}

21void link(int a,int b,int vv)

22 signed main()

27 }

view code

樹DP 小奇的倉庫 warehouse

問題 c 小奇的倉庫 warehouse 時間限制 1 sec 記憶體限制 256 mb 提交 121 解決 30 提交 狀態 題目描述 題目背景 小奇採的礦實在太多了,它準備在喵星系建個礦石倉庫。令它無語的是,喵星系的貨運飛船引擎還停留在上元時代!問題描述 喵星系有n個星球,星球以及星球間的航線形...

樹形 dp 換根 dp

樹形dp 樹形動歸一般是依賴於dfs的,根據動歸的後效性,父節點的狀態一般都依賴子節點的狀態以某種方式轉移而來 換根的p2015 設f i j 表示i的子樹上保留j條邊最多蘋果數 p2279 狀態表示f x 0 覆蓋到x的爺爺和x整棵子樹 向上2層 最少個數 f x 1 覆蓋到x的父親和x子樹 向上...

樹形DP 換根DP

某些樹形dp問題中,我們要求的值是類似 以當前節點為根節點得到的答案 卻沒有給出固定的根節點,若仍然按照常規的樹形dp思路對每個點進行dp,我們對每乙個節點均進行一次 dfs 最後的複雜度是 o left n 2 right 如果我們先假設任意乙個點為根進行 dp,求出當前樹形結構下以每個點為根的子...