BZOJ3162 獨釣寒江雪

2022-04-28 20:15:09 字數 1766 閱讀 5182

bzoj

你要給乙個樹上的每個點黑白染色,要求白點不相鄰。求本質不同的染色方案數。

兩種染色方案本質相同當且僅當對樹重新標號後對應節點的顏色相同。

\(n\le 5\times10^5\)

首先考慮沒有本質相同那個限制怎麼做。

直接設\(f_\)表示\(i\)點染成黑色/白色時子樹內的方案數。

轉移很簡單:\(f_=\prod_j (f_+f_),f_=\prod_j f_\)。

先在問題在於本質不同。那麼如果重新標號之後同構的話方案數就會多算。

考慮重新標號後重心不會變,於是以重心為根處理子樹。如果有兩個重心就新建乙個點連線這兩個點,在輸出方案的時候討論一下即可。

在\(dp\)的時候,對於乙個點\(i\)的若干個同構的子樹,應該要一起計算貢獻,設這種子樹染色的方案數是\(x\)(就是\(dp\)值),這樣的子樹一共有\(k\)棵,那麼這就是乙個可重組合,方案數為\(\binom\)。

雖然\(x\)可能會很大,但是顯然\(k\)是\(o(n)\)的,所以組合數暴力計算即可。

樹\(hash\)要寫對啊qwq。

#include#include#includeusing namespace std;

int gi()

#define ull unsigned long long

const int n = 5e5+5;

const int mod = 1e9+7;

const ull base1 = 20020415;

const ull base2 = 20011118;

int n,inv[n],to[n<<1],nxt[n<<1],head[n],cnt,sz[n],w[n],root,rt1,rt2,fg,f[2][n],tmp[n];

ull hsh[n];

void link(int u,int v)

void getroot(int u,int fa)

w[u]=max(w[u],n-sz[u]);

if (w[u]}int c(int n,int m)

bool cmp(int i,int j)

void dfs(int u,int fa)

hsh[u]=base2*len+sz[u];

for (int i=1;i<=len;++i)

hsh[u]=(hsh[u]*base1)^hsh[tmp[i]];

}int main()

w[0]=n;getroot(1,0);getroot(root,0);

for (int e=head[root],lst=0;e;lst=e,e=nxt[e])

if (sz[to[e]]*2==n)

link(n,root);link(root,n);link(n,to[e]);link(to[e],n);

rt1=root;rt2=to[e];root=n;fg=1;break;

} dfs(root,0);

if (!fg) printf("%d\n",(f[0][root]+f[1][root])%mod);

else if (hsh[rt1]==hsh[rt2]) printf("%d\n",(f[0][root]-c(f[1][rt1]+1,2)+mod)%mod);

else printf("%d\n",(1ll*f[0][rt1]*f[0][rt2]+1ll*f[0][rt1]*f[1][rt2]+1ll*f[1][rt1]*f[0][rt2])%mod);

return 0;

}

BZOJ 3162 獨釣寒江雪

題意是求一棵無根樹本質不同獨立集的個數 那個所謂 極寒點 的選取就是獨立集。結構相同就是樹同構,完全相同就是樹的形態和獨立集都相同。我們先求出樹的重心,就可以轉化為有根樹同構問題。令 f u 1 為在 u 的子樹中,選取 u 的方案樹,f u 0 為在 u 的子樹中,不選取 u 的方案數。得到最基本...

BZOJ3162 獨釣寒江雪 樹同構 DP

題解 先進行樹hash,方法是找重心,如果重心有兩個,則新建乙個虛點將兩個重心連起來,新點即為新樹的重心。將重心當做根進行hash,hash函式不能太簡單,我的方法是 將x的所有兒子的hash值排序,然後將這些hash值立方合在一起作為x的hash值。進行完樹hash後,我們考慮dp。首先不考慮同構...

BZOJ3162 獨釣寒江雪(雜湊 樹形dp)

數獨立集顯然是可以樹形dp的,問題在於本質不同。假設已經給樹確立了乙個根並且找到了所有等效 注意是等效而不是同構 子樹,那麼對轉移稍加修改使用隔板法就行了。關鍵在於找等效子樹。首先將樹的重心 若有兩個則加乙個點作為唯一重心 作為根。這樣任意極大等效子樹 比如某兩個等效子樹裡面的一部分等效,那麼裡面這...