BZOJ 1005 HNOI2008 明明的煩惱

2021-07-15 07:45:34 字數 1845 閱讀 9165

給定一棵n個節點的樹的節點的度數,其中一些度數無限制,求可以生成多少種樹。

用到了prufer數列的知識。

度娘:

prufer數列:是由有乙個對於頂點標過號的樹(標號樹)轉化來的數列,點數為n的樹轉化來的prufer數列長度為n-2。由heinz prufer於2023年在證明cayley定理時首次提出。

cayley定理:乙個完全圖k_n有n^(n-2)棵生成樹,換句話說n個節點的帶標號的無根樹有n^(n-2)個。

可以證明帶標號無根樹和prüfer編碼之間形成一一對應的關係。(具體見matrix67)

推論:

(1)標號完全二分圖(一部分的頂點標號

1 到n1

,另一部分的頂點標號n1

+1到n

)的生成樹總數等於nn

2−11

nn1−

12,其中n2=

n−n1

。 (2)n個節點的度依次為d1, d2, …, dn的標號無根樹共有(n-2)! / [ (d1-1)!(d2-1)!..(dn-1)! ]個,因為此時prüfer編碼中的數字i恰好出現di-1次。

matrix67:

acvc:

prufer序列+組合數學+高精度

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define inf (1<<30)

#define inf (1ll<<62)

#define prt cout<<#x<<":"<#define prtn cout<<#x<<":"namespace

std;

typedef

long

long ll;

template

void sc(t &x)

template

void nt(t x)

template

void pt(t x)

const

int maxn=1005;

int n,rem=0,use=0;

int prime[maxn],tot;

int cnt[maxn];

bool mark[maxn];

void init()

}}void update(int x,int f)

}struct bigint

bigint(int x)

void print()

bigint operator +(const bigint &b)const

}if(c.v[c.len]>0)c.len++;

return c;

}bigint operator *(const bigint &b)const

}c.len=len+b.len-1;

if(c.v[c.len]>0)c.len++;

while(c.len>=2&c.v[c.len-1]==0)c.len--;

return c;

}bigint operator^(int b)

}res(1);

int main()

else rem++;

}if(use<0)

update(use,-1);

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

bigint c(rem);

res=res*(c^use);

res.print();

return

0;}

狡猾的商人 bzoj1202,HNOI2005

ac通道 分析 因為每月的總收入可以為正,也可以為負,所以要比較兩個區間是否相符,當且僅當它們邊界都相同時才能比較。我們設w i 表示第1 i個月的總收入與第1 fa i 1 個月的總收入之差,及第fa i i個月的總收入。如圖。若i 1,j在同乙個集合中,則第i j個月的總收入為w j w i 1...

bzoj1005 hnoi2008 明明的煩惱

time limit 1 sec memory limit 162 mb submit 3157 solved 1262 submit status discuss 自從明明學了樹的結構,就對奇怪的樹產生了興趣.給出標號為1到n的點,以及某些點最終的度數,允許在任意兩點間連線,可產生多少棵度數滿足要...

BZOJ1005 HNOI2008 明明的煩惱

time limit 1 sec memory limit 162 mb 自從明明學了樹的結構,就對奇怪的樹產生了興趣.給出標號為1到n的點,以及某些點最終的度數,允許在 任意兩點間連線,可產生多少棵度數滿足要求的樹?第一行為n 0 n 1000 接下來n行,第i 1行給出第i個節點的度數di,如果...