啊啊啊啊,什麼東西都堆到noi前幾天來學真的是要完啊,關鍵是我還在浪啊TATAT
日常吐槽QwQ
題目大意:給定一棵樹其中某些點的度數,求有多少種樹滿足要求
orz大爺的博客%%%
prufer序列
對於一棵樹,每次選擇編號最小的葉節點,刪除它,並將與它相連的那個節點編號加入序列,直到只剩下兩個節點爲止
事實證明,樹和prufer序列是一一對應的
性質:若一個點的度數爲d,那麼它將會在序列中出現d - 1次
然後就是組合數學啦23333
令 m =
ans =
高精orz
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define N 3000
using namespace std;
int n,len,m,tot,x;
int a[N],ans[N];
void mul(int x)
{
int r = 0;
for (int i = 0;i <= len;i ++)
{
ans[i] = ans[i] * x + r;
r = ans[i] / 10;
ans[i] %= 10;
}
for (;r;r /= 10) ans[++ len] = r % 10;
}
int main()
{
scanf("%d",&n),tot = n - 2;
for (int i = 1;i <= n;i ++)
{
scanf("%d",&x);
if (x == -1) m ++;
else if (x > 1)
{
for (int j = 2;j < x;j ++) a[j] --;
tot -= x - 1;
}
}
for (int i = 2;i <= n - 2;i ++) a[i] ++;
for (int i = 2;i <= tot;i ++) a[i] --;
a[m] += tot,ans[0] = 1;
for (int i = n;i >= 2;i --)
{
for (int j = 2;j * j <= i;j ++)
if (i % j == 0) {a[j] += a[i],a[i/j] += a[i],a[i] = 0;break;}
while (a[i] --) mul(i);
}
for (int i = len;i >= 0;i --) printf("%d",ans[i]);
return 0;
}