标签:数学
传送门:BZOJ1002
似乎做法挺多,不过我并不懂得基于连通性的动态规划,于是只能做纯数学解法。
我们需要以下知识:
Kirchhoff Matrix Tree定理:
设G 为无向图,取E 为图G 的度数矩阵,F 为图G 的邻接矩阵
称矩阵E?F 为图G的Kirchhoff矩阵R ,任取与R 同构的行列式R′ 的任意一个n?1 阶主子式Q ,其值为图G的生成树个数。
这个定理不是显然的,但我们在这里不证,因为它与本题的讨论无关。
取中心点为0号点,其余点按顺时针顺序标为1234…n,则有
这里我们显然会取1-n行主子式,故
将此行列式Laplace展开,可得
其中
而将
于是有
然后高精度就可以AC了。
【吐槽:题解LaTeX代码写的时间比我做题时间还长】
代码上的小细节见下。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
struct node
{
int a[1100],l;
node()
{
memset(a,0,sizeof(a));
l = 1;
}
friend inline node operator *(int x,node &y)
{
node ret; ret.l = y.l+1;
for (int i = 1;i <= y.l;++i)
{
ret.a[i] += y.a[i]*x;
ret.a[i+1] += ret.a[i]/10;
ret.a[i] %= 10;
}
if (ret.a[ret.l] == 0) ret.l--;
return ret;
}
friend inline node operator -(node x,node y)
{
node z; z.l = max(x.l,y.l);
for (int i = 1;i <= z.l;++i)
{
z.a[i] = x.a[i]-y.a[i];
while (z.a[i] < 0)
z.a[i] += 10,x.a[i+1]--;
}
while (z.l > 1&&z.a[z.l] == 0)z.l--;
return z;
}
friend inline node operator +(node &x,int y)
{
node ret = x;
ret.a[1] += y;
for (int i = 1;i <= ret.l;++i)
{
if (ret.a[i] >= 10)
ret.a[i]-=10,ret.a[i+1]++;
else break;
}
if (ret.a[ret.l+1]) ret.l++;
return ret;
}
inline void print()
{
for (int i = l;i >= 1;--i)
printf("%d",this->a[i]);
}
};
int n;
node g[110];
node ans;
void Readdata()
{
freopen("loli.in","r",stdin);
scanf("%d",&n);
}
void Solve()
{
g[1]=g[1]+3;
g[2]=g[2]+8;
if(n<=2){
g[n].print();
return;
}
for(int i=3;i<=n;i++)
g[i]=3*g[i-1]-g[i-2];
ans=3*g[n-1]-2*g[n-2];
ans=ans+(-2);
ans.print();
}
void Close()
{
fclose(stdin);
fclose(stdout);
}
int main()
{
Readdata();
Solve();
Close();
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:数学
原文地址:http://blog.csdn.net/le_ballon_rouge/article/details/47609531