一道很好的換根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
1view code//這個異或是個狗屎啊!!!但是其實異或的二進位制位也不超過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 }
樹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,求出當前樹形結構下以每個點為根的子...