日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

树的计数(prufer序列 或 purfer序列)

發布時間:2023/12/2 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 树的计数(prufer序列 或 purfer序列) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?題解

首先我們要知道一條性質,prufer序列中的某個點出現次數為該點在樹中度數-1

感性理解一下,其實按照prufer序列求法自己推一下就出來了

設題目里給的度為$d[]$

先將所有的d--

然后按照排列組合得出來

這是多重集排列數

首先從n-2中選擇d[1]個數是$C_{n}^{d[1]}$然后再從剩余n-d[1]中選d[2] $C_{n-d[1]}^{d[2]}$依次類推

$C_{n-2}^{d[1]}\times C_{n-2-d[1]}^{d[2]}\times C_{n-2-d[1]-d[2]}^{d[3]}\times ……\times C_{n-2-d[1]-……-d[n-1]}^{d[n]}$

得到

$\frac{(n-2)!}{\sum\limits_{i=1}^{n}d[i]!}$

高精轉移就完了

還是過不了?

一些特判:

首先該題會有無解的情況

然后當只有一個點時方案數為1

然后當出現度數為0的點時方案數要特殊處理

以下是本人丑陋的代碼

#include<bits/stdc++.h> #define ll long long #define N 10 #define P 1 using namespace std; ll n,m,d[20000],cnt=0; bool flag[20000]; struct bignum {ll n[200000],l;bignum(){l=1,memset(n,0,sizeof(n));}void clear(){while(l>1&&!n[l-1]) l--;}void print(){printf("%lld",n[l-1]);for(ll i=l-2;i>=0;i--)printf("%0*lld",P,n[i]);printf("\n");}bignum operator = (ll x){l=0; while(x){n[l++]=x%N;x/=N;}return *this;}bignum operator +(bignum x) const{bignum t=*this;if(x.l>t.l) t.l=x.l; for(ll i=0;i<t.l;i++){t.n[i]+=x.n[i];if(t.n[i]>=N){t.n[i+1]+=t.n[i]/N;t.n[i]%=N;}}return t;}bignum operator * (const ll& b){bignum c;c.l=0;for(ll i=0,g=0;g||i<l;i++){ll x;if(i<l)x=n[i]*b+g;else x=g;c.n[c.l++]=x%N;g=x/N;}return c;}bignum operator *(bignum x) const{bignum t=*this,tep;tep.l=t.l+x.l+1;for(ll i=0;i<t.l;i++)for(ll j=0;j<=x.l;j++){tep.n[i+j]+=t.n[i]*x.n[j];}for(ll i=0;i<tep.l;i++){tep.n[i+1]+=tep.n[i]/N;tep.n[i]%=N;}tep.clear();return tep;}bool operator <(bignum x) const{bignum t=*this,tep;if(t.l!=x.l) return t.l<x.l;for(ll i=t.l-1;i>=0;i--){if(t.n[i]!=x.n[i]) return t.n[i]<x.n[i];}return 0;}bool operator >(bignum x) const{bignum t=*this;if(t.l!=x.l) return t.l>x.l;for(ll i=t.l-1;i>=0;i--){if(t.n[i]!=x.n[i]) return t.n[i]>x.n[i];}return 0;}bignum operator -(bignum x) const{bignum t=*this;if(t<x) printf("-"),swap(t,x);ll jie=0;for(ll i=0;i<t.l;i++){t.n[i]-=x.n[i];while(t.n[i]<0){t.n[i]+=N;jie++;}t.n[i+1]-=jie;jie=0;;}t.clear();return t;}bignum operator /(const ll &x){bignum t=*this,r;ll tmp=0;r.l=t.l;for(ll i=t.l-1;i>=0;i--){tmp+=t.n[i];if(tmp>=x){r.n[i]=tmp/x;tmp%=x;}tmp*=N;}r.clear();return r;} }ans; bignum jie(ll x) {bignum t;t=1;for(ll i=2;i<=x;i++){t=x*i;}return t; } int main() {memset(flag,0,sizeof(flag));ll sum=0,you0=0;scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld",&d[i]);if(d[i])flag[i]=1,cnt++;else you0=1;d[i]--,sum+=d[i];}if(you0&&n==1){cout<<1<<endl;return 0;}if(sum!=n-2||you0) {cout<<0<<endl;return 0;}ans=1;for(ll i=2;i<=cnt-2;i++)ans=ans*i;for(ll i=1;i<=n;i++){if(flag[i])for(ll j=2;j<=d[i];j++)ans=ans/j;}ans.print(); }

?

轉載于:https://www.cnblogs.com/znsbc-13/p/11222262.html

總結

以上是生活随笔為你收集整理的树的计数(prufer序列 或 purfer序列)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。