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. alibaba/fescar 阿里巴巴 开源 分布式事务中间件

    Fescar 是 阿里巴巴 开源的 分布式事务中间件,以 高效 并且对业务 0 侵入 的方式,解决 微服务 场景下面临的分布式事务问题. 示例:https://github.com/windwant/ ...

  2. 006 --MySQL索引原理

    一 .索引的概念? 一般的应用系统,读写比例在10:1左右,而且插入操作和一般的更新操作很少出现性能问题,在生产环境中,我们遇到最多的,也是最容易出问题的,还是一些复杂的查询操作,因此对查询语句的优化 ...

  3. js 的filter()方法

    filter()方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组. filter()基本语法: arr.filter(callback[, thisArg]) filter() ...

  4. chown命令详情

    基础命令学习目录首页 原文链接:https://www.jb51.net/article/98255.htm chown将指定文件的拥有者改为指定的用户或组,用户可以是用户名或者用户ID:组可以是组名 ...

  5. Python序列之列表 (list)

    作者博文地址:http://www.cnblogs.com/spiritman/ 列表是Python中最基本的数据结构,是Python最常用的数据类型.Python列表是任意对象的有序集合,通过索引访 ...

  6. 利用Python编写Windows恶意代码!自娱自乐!勿用于非法用途!

    本文主要展示的是通过使用python和PyInstaller来构建恶意软件的一些poc. 利用Python编写Windows恶意代码!自娱自乐!勿用于非法用途!众所周知的,恶意软件如果影响到了他人的生 ...

  7. Hadoop Streaming框架使用(二)

    上一篇文章介绍了Streaming的各种参数,本文具体介绍使用方法. 提交hadoop任务示例: $HADOOP_HOME/bin/hadoop streaming \ -input /user/te ...

  8. 分布式高并发下全局ID生成策略

    数据在分片时,典型的是分库分表,就有一个全局ID生成的问题.单纯的生成全局ID并不是什么难题,但是生成的ID通常要满足分片的一些要求:   1 不能有单点故障.   2 以时间为序,或者ID里包含时间 ...

  9. MathExam任务一

    小学一二年级数学计算题 一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟) Planning 计划 60 35 • Es ...

  10. Hibernate left join

    6.4.5  左外连接 左外连接(Left Outer Join)查询出左表对应的复合条件的所有记录,如查询李晓梅同学的选课信息.下面是类HQLLeftOuterJoinQuery的源代码. 其实关联 ...