一看题……矩阵树定理秒杀……
等等……我连行列式都不会求用什么矩阵树定理……
于是就只能推式子了。
让我们暂时先把环剖成链,于是问题就变成了一个类似整数剖分的形式:
d[i]=∑j=1i−1d[j]∗(i−j)
d
[
i
]
=
∑
j
=
1
i
−
1
d
[
j
]
∗
(
i
−
j
)
要乘上 i−j i − j 的原因在于每划分出一个大小为 i−j i − j 的联通块,中心点都可以向它的某一点连一条边。
然而题目中是环,因此就需要考虑大小为
i
i
的联通块的情况,明显共有种,故完整表达式为:
d[i]=i2+∑j=1i−1d[j]∗(i−j)
d
[
i
]
=
i
2
+
∑
j
=
1
i
−
1
d
[
j
]
∗
(
i
−
j
)
注意要写高精度(好恶心啊),具体细节见代码。
代码如下:
#include <bits/stdc++.h>
using namespace std;
struct BigI
{
long long a[1000];
BigI(long long n=0)
{
memset(a,0,sizeof(a));
a[0]=n;
}
BigI friend inline operator+(BigI a1,BigI a2)
{
for(long long i=0,j=0;i<1000;i++)
{
a1.a[i]+=a2.a[i]+j;
j=a1.a[i]/10;
a1.a[i]%=10;
}
return a1;
}
BigI friend inline operator*(BigI a1,int n1)
{
for(long long i=0,j=0;i<1000;i++)
{
a1.a[i]*=n1;
a1.a[i]+=j;
j=a1.a[i]/10;
a1.a[i]%=10;
}
return a1;
}
void print()
{
int i=999;
for(;!a[i];i--);
for(;i>=0;i--)cout<<a[i];
cout<<endl;
}
}a[110];
int n;
int main()
{
cin>>n;
a[1].a[0]=1;
for(int i=2;i<=n;i++)
{
a[i]=BigI(i*i);
for(int j=1;j<i;j++)
{
a[i]=a[i]+a[j]*(i-j);
}
}
a[n].print();
return 0;
}