JSOI2016 獨特的樹葉

2021-10-25 05:14:58 字數 1672 閱讀 7274

點此看題

其實就是判斷樹同構,然後自然聯想到了樹has

hhash

hash

簡單介紹一下樹雜湊的方法,我們先求出子樹的has

hhash

hash

值g [i

]g[i]

g[i]

,我用的是質數+

++自然溢位的方式,設p[i

]p[i]

p[i]

為第i

ii個質數,那麼轉移:

g [u

]=1+

∑g[v

]×p[

siz[

v]

]g[u]=1+\sum g[v]\times p[siz[v]]

g[u]=1

+∑g[

v]×p

[siz

[v]]

那麼對於u

uu點為根的雜湊值hs[

u]

hs[u]

hs[u

],就可以再跑一遍dfs

dfsdf

s求出了。

回到此題,對於第一棵樹,我們可以把每個點為根的雜湊值放進map

mapma

p中方便第二棵樹查詢。然後對於第二棵樹,我們列舉他的乙個葉子,然後看刪去這個葉子後他父親為根的has

hhash

hash

值,注意1

11為根的話是需要特判的(我們定的根有可能是葉子),然後去map

mapma

p裡面找有沒有這個has

hhash

hash

值就可以判斷是否合法。

我的常數比較優秀,在 luo

gu

\tt luogu

luog

u 上可以操到 ran

k2

\tt rank2

rank

2

#include

#include

using

namespace std;

const

int m =

200005

;#define ull unsigned long long

intread()

int cnt,p[m]

;bool vis[

15*m]

; map<

int,ull> mp;

struct edge

;void

init

(int n)}}

struct tree

,f[u]

=tot;

e[++tot]

=edge

,f[v]

=tot;

}dfs(1

,0);

dfs2(1

,0);

}void

dfs(

int u,

int fa)

}void

dfs2

(int u,

int fa)

}}t1,t2;

intmain()

}for

(int i=

2;i<=t2.n;i++)if

(t2.siz[i]==1

)//找葉子

}}

JSOI2016 獨特的樹葉

仙題 1.我們發現如果能夠求出來 a 樹中任何乙個點當根的時候的 hash 值,那麼就可以求出答案了。然後你隨便寫一寫 hash 策略改成 xor 發現 xor 的逆運算就是 xor 好啊!換根 dp 直接求出我們需要的,然後放到 set 去就行了。include include include i...

JSOI2016 獨特的樹葉

有一顆大小為 n 的樹 a 現加上乙個節點並打亂編號,形成樹 b 詢問加上的節點最後編號是多少?判斷樹的同構顯然需要樹雜湊。可以先將樹 a 中以每個節點為根的雜湊值算出來存進乙隻 unordered set 中,然後在樹 b 中隨便找乙個不是葉節點的節點為根,列舉去掉乙個葉節點,看根的 hash 值...

JSOI2016 獨特的樹葉(樹雜湊)

這個題只要求出以每個點為根的有根 無標號 樹的hash值就好了。我以前的樹雜湊是把樹轉為括號序,這個太麻煩了。一種方法是每個點的權值定義為siz,找到乙個dfs序,使得經過的點的權值字典序組最小。這個對於這道題也不方便,因為換根是可能需要字首和字尾和搞。在網上看到一種的hash是這個 f x 1 s...