樹DP 小奇的倉庫 warehouse

2022-03-27 07:32:59 字數 1608 閱讀 5823

問題 c: 小奇的倉庫(warehouse)

時間限制: 1 sec 記憶體限制: 256 mb

提交: 121 解決: 30

[提交][狀態]

題目描述

【題目背景】

小奇採的礦實在太多了,它準備在喵星系建個礦石倉庫。令它無語的是,喵星系的貨運飛船引擎還停留在上元時代!

【問題描述】

喵星系有n個星球,星球以及星球間的航線形成一棵樹。

從星球a到星球b要花費[dis(a,b) xor m]秒。(dis(a,b)表示ab間的航線長度,xor為位運算中的異或)

為了給倉庫選址,小奇想知道,星球i(1<=i<=n)到其它所有星球花費的時間之和。

【輸入格式】

第一行包含兩個正整數n,m。

接下來n-1行,每行3個正整數a,b,c,表示a,b之間的航線長度為c。

【輸出格式】

n行,每行乙個整數,表示星球i到其它所有星球花費的時間之和。

【樣例輸入】

4 01 2 1

1 3 2

1 4 3

【樣例輸出】

12 【資料範圍】略

保證答案不超過2*10^9

但看著資料範圍,只能是o(n)效率。

首先想想m=0的情況:完全不用^,那麼兩遍dfs就解決問題了。主題思路就是一邊算兒子傳到父親的,一遍算父親傳到兒子的。

再考慮m=1的情況,只要知道有多少個點到自己的距離是奇數,多少是偶數就行。也就是兩遍dfs時多傳個參,再根據邊權是奇是偶討論一下就好了。

我們延續上面的思路,m<=15,也就是說只會改變後四位的值,同理,我們記錄後四位的值就好了,傳遞時,只要把後四位的值+邊權,再取後四位即可。

到頭來就是兩遍dfs。

#include 

#include

#include

#include

#include

using namespace std;

#define n 100006

intread()

while(x>='0'&&x

<='9')

return sum*f;

}struct roadlu[n*2];

int n,m,e,adj[n],f[n],g[n],sz[n],up[n][17];

void add(int u,int v,int l);adj[u]=e;}

void dfs1(int

x,int fa)

up[x][l-(l>>4

<<4)]++;

}}void dfs2(int

x,int fa,int cnt)

d[l-(l>>4

<<4)]--;

for(int j=0;j<16;j++)

up[to][l-(l>>4

<<4)]++;

dfs2(to,x,s-sz[to]);

}}int main()

dfs1(1,0);

dfs2(1,0,0);

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

printf("%d\n",g[i]);

}}

小奇的倉庫 換根dp

一道很好的換根dp題。考場上現場yy十分愉快 給定樹,求每個點的到其它所有點的距離異或上m之後的值,n 100000,m 16 只能線性複雜度求解,m又小得奇怪。或者帶乙個log像kx一樣打乙個線段樹 我們可以發現,m小的話對距離很大的路徑的影響也不會超過16。那麼變化的其實就是最後4個二進位制位啊...

小奇的數列

題目 背景 小奇總是在數學課上思考奇怪的問題。問題描述 給定乙個長度為 n 的數列,以及 m 次詢問,每次給出三個數 l,r 和 p,詢問 a l a l 1 a r mod p 的最小值。其中 l l r r。即模意義下的區間子串和最小值。輸入格式 第一行包含兩個正整數 n 和 m,表示數列的長度...

Luogu U16325小奇的花園(樹鏈剖分)

題目鏈結 學了學動態開點的樹鏈剖分,其實跟動態開點的線段樹差不多啦 查詢的時候別ssbb地動態開點,如果沒這個點果斷返回0就行 只要注意花的種類能到intmax就行qwq!include include include include include include define mid l r 1...