P2144 [FJOI2007]轮状病毒

题目描述

轮状病毒有很多变种。许多轮状病毒都是由一个轮状基产生。一个\(n\)轮状基由圆环上\(n\)个不同的基原子和圆心的一个核原子构成。\(2\)个原子之间的边表示这\(2\)个原子之间的信息通道,如图\(1\)。

\(n\)轮状病毒的产生规律是在\(n\)轮状基中删除若干边,使各原子之间有唯一一条信息通道。例如,共有\(16\)个不同的\(3\)轮状病毒,如图\(2\)所示。

给定\(n(n\le100)\),编程计算有多少个不同的\(n\)轮状病毒。

输入输出格式

输入格式:

第一行有\(1\)个正整数\(n\)。

输出格式:

将编程计算出的不同的\(n\)轮状病毒数输出


发现题目要求求出看起来很有规律的无向图生成树个数,显然可以找一些规律/打表/递推之类的,但不妨采用比较暴力的方法,矩阵树定理。

然后发现事情并没有那么简单,如果用矩阵树定理暴力去做的话,你可以选择一些乱搞/手写高精度小数类之类的方法

而之前又说,这个图比较特殊,所以,我们可以研究一下基尔霍夫矩阵的行列式有没有什么比较特殊的求法,\(n+1(n>2)\)阶的基尔霍夫矩阵大概长这个样子

\[\begin{bmatrix}n&-1&-1&-1&-1&\cdots&-1&-1&-1\\-1&3&-1&0&0&\cdots&0&0&-1\\-1&-1&3&-1&0&\dots&0&0&0\\-1&0&-1&3&-1&\cdots&0&0&0\\\vdots&\vdots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\-1&0&0&0&0&\cdots&-1&3&-1\\-1&-1&0&0&0&\cdots&0&-1&3\end{bmatrix}
\]

\(n\)阶主子式肯定是扔第一行第一列啊,因为我们想找行列式的递推规律,然后变成这样

\[\begin{bmatrix}3&-1&0&0&\cdots&0&0&-1\\-1&3&-1&0&\dots&0&0&0\\0&-1&3&-1&\cdots&0&0&0\\\vdots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\0&0&0&0&\cdots&-1&3&-1\\-1&0&0&0&\cdots&0&-1&3\end{bmatrix}
\]

设这个矩阵为\(A_n\),那么\(n\)的答案就是\(\det A_n\),然后我们考虑求出这个矩阵的行列式

由“行列式等于它的任一行(列)的各元素与其对应的代数余子式乘积之和”

  • 余子式:在\(n\)阶行列式中,把元素\(a_{i,j}\)所在第\(i\)行和第\(j\)行划去后,留下的\(n-1\)阶行列式叫元素\(a_{i,j}\)的余子式,记做\(M_{i,j}\),定义代数余子式为\(A_{i,j}=(-1)^{i+j}M_{i,j}\)

我们可以扔第一行,因为\((1,n)\)和\((n,1)\)两个位置的东西看起来巨难受。

拆开第一行第一列得到

\[3\begin{vmatrix}3&-1&0&\dots&0&0&0\\-1&3&-1&\cdots&0&0&0\\\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\0&0&0&\cdots&-1&3&-1\\0&0&0&\cdots&0&-1&3\end{vmatrix}
\]

这个看起来就可以递推的东西,设\(n-1\)阶的它为\(B_{n-1}\)。为了方便,以下\(A_n,B_n\)也指代行列式的值。

然后剩下有贡献的第一行第二列和第一行第\(n-1\)列,因为余子式的正负与\(n\)有关,不妨先设\(n\)为奇数,偶数的情况是一样的。

\[\begin{vmatrix}-1&-1&0&\dots&0&0&0\\0&3&-1&\cdots&0&0&0\\\vdots&\vdots&\vdots&\ddots&\vdots&\vdots&\vdots\\0&0&0&\cdots&-1&3&-1\\-1&0&0&\cdots&0&-1&3\end{vmatrix}
\]

这是拆了第一行第二列,没思路再拆,发现扔第一行第一列后是\(-B_{n-2}\),扔第\(n-1\)行第\(1\)列是主对角线全为\(-1\)的下三角,行列式的值为\(-1\),再乘上\((-1)^{n-1+1}(-1)\)还是\(-1\)

然后是第一行第\(n\)列

\[-\begin{vmatrix}-1&3&-1&0&\dots&0&0\\0&-1&3&-1&\cdots&0&0\\\vdots&\vdots&\vdots&\vdots&\ddots&\vdots&\vdots\\0&0&0&0&\cdots&-1&3\\-1&0&0&0&\cdots&0&-1\end{vmatrix}
\]

注意这里是负的,因为\(n\)是奇数。然后还是拆第一列,发现答案还是\(-B_{n-2}\)和\(-1\)

于是我们有\(A_n=3B_{n-1}-2B_{n-2}-2\)

以同样的方法对\(B\)做讨论,可以得到\(B_n=3B_{n-1}-B_{n-2}\)

然后联立一下得到\(A_{n}=3A_{n-1}-A_{n-2}+2\),带入到\(n\le2\)发现式子仍然成立,然后直接递推+高精即可。


Code:

#include <cstdio>
#include <cstring>
const int N=110;
struct bignum
{
int num[N];
bignum(){memset(num,0,sizeof(num));}
bignum friend operator +(bignum n1,bignum n2)
{
int len=n1.num[0]>n2.num[0]?n1.num[0]:n2.num[0];
for(int i=1;i<=len;i++)
{
n1.num[i]+=n2.num[i];
n1.num[i+1]+=n1.num[i]/10;
n1.num[i]%=10;
}
if(n1.num[len+1]) n1.num[0]=len+1;
else n1.num[0]=len;
return n1;
}
bignum friend operator -(bignum n1,bignum n2)
{
int len=n1.num[0];
for(int i=1;i<=len;i++)
{
n1.num[i]-=n2.num[i];
if(n1.num[i]<0)
n1.num[i]+=10,n1.num[i+1]--;
}
if(n1.num[len]) n1.num[0]=len;
else n1.num[0]=len-1;
return n1;
}
}ans[N],two;
int main()
{
int n;scanf("%d",&n);
ans[1].num[0]=1,ans[1].num[1]=1,ans[2].num[0]=1,ans[2].num[1]=5,two.num[0]=1,two.num[1]=2;
for(int i=3;i<=n;i++) ans[i]=ans[i-1]+ans[i-1]+ans[i-1]-ans[i-2]+two;
for(int i=ans[n].num[0];i;i--) printf("%d",ans[n].num[i]);
return 0;
}

2018.12.20

洛谷 P2144 [FJOI2007]轮状病毒的更多相关文章

  1. 洛谷P2144 [FJOI2007]轮状病毒

    可以用Matrix-Tree定理,然而被卡精度 #include<cstdio> #include<cstdlib> #include<algorithm> #in ...

  2. 洛谷 P2144 BZOJ 1003 [FJOI2007]轮状病毒

    题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间的信息通道,如图1. n轮状病毒的产生规律 ...

  3. P2144 [FJOI2007]轮状病毒

    题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间的信息通道,如图1. n轮状病毒的产生规律 ...

  4. luogu P2144 [FJOI2007]轮状病毒

    传送门 随便摸一发题解算了 打表找规律 前五个答案是 1 5 16 45 121 其实是 1^2 3^2-4 4^2 7^2-4 11^2 底数就是类似于斐波那契数列,还有偶数项要减4 #includ ...

  5. 【洛谷】2144:[FJOI2007]轮状病毒【高精度】【数学推导??(找规律)】

    P2144 [FJOI2007]轮状病毒 题目描述 轮状病毒有很多变种.许多轮状病毒都是由一个轮状基产生.一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成.2个原子之间的边表示这2个原子之间 ...

  6. 洛谷1640 bzoj1854游戏 匈牙利就是又短又快

    bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...

  7. 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.

    没有上司的舞会  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond       题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...

  8. 洛谷P1108 低价购买[DP | LIS方案数]

    题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...

  9. 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP

    题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...

随机推荐

  1. RabbitMQ入门:Hello RabbitMQ 代码实例

    在之前的一篇博客RabbitMQ入门:认识并安装RabbitMQ(以Windows系统为例)中,我们安装了RabbitMQ并且对其也有的初步的认识,今天就来写个入门小例子来加深概念理解并了解代码怎么实 ...

  2. Python中格式化format()方法详解

    Python中格式化format()方法详解 Python中格式化输出字符串使用format()函数, 字符串即类, 可以使用方法; Python是完全面向对象的语言, 任何东西都是对象; 字符串的参 ...

  3. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第2节: FastThreadLocal的set方法

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第二节: FastThreadLocal的set方法 上一小节我们学习了FastThreadLocal的创建和 ...

  4. spring-boot+swagger实现WebApi文档

    1.引用依赖包 <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-s ...

  5. SQL面经汇总

    转载链接:https://www.nowcoder.com/discuss/95812 目前的打算是还要写一个假设检验的汇总和机器学习的汇总. 之前写的概率论汇总: https://www.nowco ...

  6. nodejs 服务器实现区分多客户端请求服务

    初始实现 var net = require('net');//1 引入net模块 var chatServer = net.createServer();//创建net服务器 var clientL ...

  7. 2018年第九届蓝桥杯【C++省赛B组】

    2标题:明码 汉字的字形存在于字库中,即便在今天,16点阵的字库也仍然使用广泛.16点阵的字库把每个汉字看成是16x16个像素信息.并把这些信息记录在字节中. 一个字节可以存储8位信息,用32个字节就 ...

  8. prototype原型(待完善)

    模式:prototype  解决向量的深浅克隆 #pragma once #ifndef _PROTOTYPE_H_ #define _PROTOTYPE_H_ class Prototype{ pu ...

  9. 使用JavascriptExecutor改变页面元素

    如下如html的页面代码 <html> <body> <input type="text" name="text" value=& ...

  10. JDK和CGLIB动态代理原理

    1.JDK动态代理利用拦截器(拦截器必须实现InvocationHanlder)加上反射机制生成一个实现代理接口的匿名类, 在调用具体方法前调用InvokeHandler来处理. 2.CGLiB动态代 ...