BZOJ1005 HNOI2008 明明的煩惱

2022-05-16 06:51:20 字數 1856 閱讀 2786

自從明明學了樹的結構,就對奇怪的樹產生了興趣......給出標號為1到n的點,以及某些點最終的度數,允許在

任意兩點間連線,可產生多少棵度數滿足要求的樹?

第一行為n(0 < n < = 1000),

接下來n行,第i+1行給出第i個節點的度數di,如果對度數不要求,則輸入-1

乙個整數,表示不同的滿足要求的樹的個數,無解輸出031

-1-1

兩棵樹分別為1-2-3;1-3-2

接下來我們需要使用purfer sequence。

purfer sequence

將一棵無根樹按照以下原則構造出來的序列稱為這棵樹的purfer sequence。若樹的大小為n,則這樣的序列長度為n-2。

原則:每次找到當前樹中度數為1的、編號最小的點,將這個點的父親加入序列中,同時將這個點從樹上刪去

這個序列有許多性質,比如每個purfer sequence 對應唯一的一棵無根樹。但是,我們要用的是另乙個非常重要的性質:

對於樹上的每乙個節點\(i\),設度數為\(d_i\),那麼\(i\)在序列中會出現\(d_i-1\)次。

有了這個性質之後,再看這道題。假設我們已經知道了每個點的度數,那麼滿足條件的無根樹的方案數為:

\[ans=\frac^(d_i-1)!}

\]這就是乙個可重排列的公式。但是,現在有些點是沒有限制的,而序列長度只能是\(n-2\)。所以,記:

\[cnt=\sum_^n[d_i!=-1]\\sum=\sum_^n[d_i!=-1]\times (d_i-1)

\]那麼,乙個合法的方案就是在\(n-2\)個位置中選擇\(sum\)個,這些位置進行可重排列。剩下的位置可以在\(n-cnt\)個點中隨便放。方案數為:

\[ans=c_^\frac^n [d_i!=-1]\times (d_i-1)!}\times (n-cnt)^

\]化簡可得:

\[ans=\frac^n [d_i!=-1]\times (d_i-1)!}\times (n-cnt)^

\]當然,單是這麼寫還需要高精度乘除法。我們可以利用質因數分解,將最後的答案變為質因數相乘的形式,然後就可以用高精度乘低精度計算了。

注意,purfer sequence 可以解決大部分與度數有關的樹的計數問題。

#include #include #define n 1000002

using namespace std;

int n,sum,cnt,i,j,k,d[n],p[n],c[n],num,ans[n],l;

bool vis[n];

int read()

while(c<='9'&&c>='0')

return w*f;

}void change(int x,int op)

}int main()

} for(i=1;i<=n;i++)

} if(n==1)

else if(n==2)

for(i=1;i<=n;i++)

} for(i=2;i<=n-2;i++) change(i,1);

for(i=2;i<=n-sum-2;i++) change(i,-1);

for(i=1;i<=n-sum-2;i++) change(n-cnt,1);

ans[1]=l=1;

for(i=2;i<=1000;i++)

while(tmp) ans[++l]=tmp%10,tmp/=10;

} }for(i=l;i>=1;i--) printf("%d",ans[i]);

puts("");

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的點,以及某些點最終的度數,允許在任意兩點間連線,可產生多少棵度數滿足要...

BZOJ 1005 HNOI2008 明明的煩惱

給定一棵n個節點的樹的節點的度數,其中一些度數無限制,求可以生成多少種樹。用到了prufer數列的知識。度娘 prufer數列 是由有乙個對於頂點標過號的樹 標號樹 轉化來的數列,點數為n的樹轉化來的prufer數列長度為n 2。由heinz prufer於1918年在證明cayley定理時首次提出...