BZOJ1002【FJOI2007】轮状病毒
1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 6917 Solved: 3777
[Submit][Status][Discuss]
Description
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子
和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
.png)
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不
同的3轮状病毒,如下图所示
.png)
Input
第一行有1个正整数n
Output
计算出的不同的n轮状病毒数输出
Sample Input
Sample Output
HINT
Source
题解:
一道及其艰辛的推导题;(感觉bzoj的前两个题对新人不太友好啊)
当然可以用基尔霍夫矩阵;
打表可得$g_i = 3g_{i-1} - g_{i-2} + 2$;再用一个高精度就好了
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>
#include<vector>
#include<stack>
#include<map>
#define Run(i,l,r) for(int i=l;i<=r;i++)
#define Don(i,l,r) for(int i=l;i>=r;i--)
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int N=,base = 1e4;
int n;
struct Bign{
int c[N],len;
Bign(){memset(c,,sizeof(c));len=;}
void zero(){while(len&&!c[len])len--;}
void print(){
zero();
printf("%d",c[len]);
Don(i,len-,)printf("%04d",c[i]);
puts("");
}
Bign operator -(const Bign&A){
Bign ret;
ret.len = len;
for(int i=;i<=len;i++){
ret.c[i] += c[i] - A.c[i];
if(ret.c[i]<){
ret.c[i] += base;
ret.c[i + ] --;
}
}
ret.zero();
return ret;
}
Bign operator +(const int&A){
Bign ret;
ret = *this;
ret.len = len + ;
ret.c[] += A;
for(int i=;i<=len;i++){
if(ret.c[i]>=base){
ret.c[i] -= base;
ret.c[i+] ++;
}
}
ret.zero();
return ret;
}
Bign operator *(const int&A){
Bign ret;
ret.len = len + ;
for(int i=;i<=len;i++){
ret.c[i] = c[i] * A;
}
for(int i=;i<=len;i++){
if(ret.c[i]>=base){
ret.c[i+]+=ret.c[i]/base;
ret.c[i] %= base;
}
}
ret.zero();
return ret;
}
}f[N];
int main(){
freopen("bzoj1002.in","r",stdin);
freopen("bzoj1002.out","w",stdout);
scanf("%d",&n);
f[].len = ;
f[].c[] = ;
f[].len = ;
f[].c[] = ;
//f[1].print();
//f[2].print();
for(int i=;i<=n;i++){
f[i] = f[i-]* - f[i-] + ;
// f[i].print();
}
f[n].print();
return ;
}//by tkys_Austin;
可以用递推证明:
①先不考虑中间的点,最后再将中间的点和外面的点连起来,假设某种方案将外面的环分成了i条链,每条的点数为si,每个链都可以任选一个点连上中间的点,这种方案的贡献就为$\prod_i si$,设长度为i的链分成若干链的$\sum \prod_i si$为$f_i$,轮状病毒的总方案的为$g_i$
$g_n$的转移枚举第一个点所在的链的长度s1,此时1的位置一共有s1种可能,再乘上剩下的长度为n-s1的链的方案数$f_{n-s1}$;
$f_n$的转移枚举最后一段链的长度,用最后一段链的长度乘剩下的$f_j$
$$\left\{\begin{array}{c}f_0 = 1\\f_i = \sum_{j=0}^{i} (j-i)f_j\end{array}\right.$$
$$\left \{ \begin{array}{c} g_0 = 1\\g_i = \sum_{j=0}^{i} (j-i)^2 {f_j} \end{array}\right.$$
我们先证明:$f_{i-1} + f_{i+1} = 3f_{i}$
$$f_{i-1} + f_{i+1}\\= \sum_{j=0}^{i-1}(i-1-j)f_{j} + \sum_{j=0}^{i+1}(i+1-j)f_{j} \\= \sum_{j=0}^{i-1}2(i-j)f_{j} + f_i \\= 2 \sum_{j=0}^{i}(i-j)f_{j} + f_i \\= 2 f_i + f_i \\= 3 f_i $$
再对g同样操作:
$$g_{i-1} + g_{i+1} \\
= \sum_{j=0}^{i+1}(i+1-j)^2 f_j + \sum_{j=0}^{i-1}(i-1-j)^2 f_j \\
= \sum_{j=0}^{i-1}((i+1-j)^2 + (i-1-j)^2) f_j + f_i \\
= \sum_{j=0}^{i-1}2((i-j)^2 + 1)f_j + f_i \\
= 2 \sum_{j=0}^{i}(i-j)^2 f_j + 2 \sum_{j=0}^{i-1}f_j + f_i \\
= 2 g_i + 2 + 2 \sum_{j=1}^{i-1}f_j + fi \\
$$尝试把右边那坨化成理想的目标$g_i$:
$$2\sum_{j=1}^{i-1}f_{j} + f_{i} \\
= 2\sum_{j=1}^{i-1}\sum_{k=0}^{j}(j-k)f_{k} + f_{i} $$
改变一下求和顺序 \\
$$= 2\sum_{k=0}^{i-1}f_{k} \sum_{j>k}^{i-1}(j-k) + f_{i} $$
不知道我下标写对没有。。。后面的1直接求 \\
$$= 2\sum_{k=0}^{i-1}f_{k} \frac{(i-1-k)(i-k)}{2} + f_{i} $$
看到分子出现2,感觉有希望QAQ,约掉
$$ = \sum_{k=0}^{i-1}f_{k} (i-1-k)(i-k) + f_{i} $$ $$ = \sum_{k=0}^{i-1}(i-k)^2 f_{k} - \sum_{k=0}^{i-1}(i-k)f_{k} + f_{i} $$ $$ = \sum_{j=0}^i (i-j)^{2} f_j - \sum_{j=0}^i (i-j) f_j + f_i$$ $$ = g_{i} - f_{i} + f_{i} \\= g_{i} $$
带回去就是原来的式子了。。。。。。。。。
(mathjax好难用。。。。。)
BZOJ1002【FJOI2007】轮状病毒的更多相关文章
- BZOJ1002 FJOI2007 轮状病毒 【基尔霍夫矩阵+高精度】
BZOJ1002 FJOI2007 轮状病毒 Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原 ...
- [bzoj1002][FJOI2007]轮状病毒_递推_高精度
轮状病毒 bzoj-1002 FJOI-2007 Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2 ...
- bzoj1002: [FJOI2007]轮状病毒(基尔霍夫矩阵)
1002: [FJOI2007]轮状病毒 题目:传送门 题解: 决定开始板刷的第一题... 看到这题的时候想:这不就是求有多少种最小生成树的方式吗? 不会啊!!!%题解... 什么鬼?基尔霍夫矩阵?? ...
- BZOJ1002[FJOI2007]轮状病毒
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下 ...
- [bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图 ...
- [BZOJ1002] [FJOI2007] 轮状病毒 (数学)
Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Inpu ...
- [luogu2144][bzoj1002][FJOI2007]轮状病毒【高精度+斐波那契数列+基尔霍夫矩阵】
题目描述 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病 ...
- bzoj1002: [FJOI2007]轮状病毒 生成树计数
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规 ...
- BZOJ1002:[FJOI2007]轮状病毒(找规律,递推)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下 ...
- [bzoj1002] [FJOI2007]轮状病毒轮状病毒(基尔霍夫矩阵)
Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下 ...
随机推荐
- Scala基础知识笔记1
上一篇文章介绍了如何下载scala, 因为在官网上点击下载按钮无法下载, 下面介绍scala的基础语法: 1 scala和java的关系 Scala是基于jvm的一门编程语言,Scala的代码最终会经 ...
- 《Angular4从入门到实战》学习笔记
<Angular4从入门到实战>学习笔记 腾讯课堂:米斯特吴 视频讲座 二〇一九年二月十三日星期三14时14分 What Is Angular?(简介) 前端最流行的主流JavaScrip ...
- 高可用Kubernetes集群-12. 部署kubernetes-ingress
参考文档: Github:https://github.com/kubernetes/ingress-nginx Kubernetes ingress:https://kubernetes.io/do ...
- [转载]linux+nginx+python+mysql安装文档
原文地址:linux+nginx+python+mysql安装文档作者:oracletom # 开发包(如果centos没有安装数据库服务,那么要安装下面的mysql开发包) MySQL-devel- ...
- JAVA学习笔记--接口
一.抽象类和抽象方法 在谈论接口之前,我们先了解一下抽象类和抽象方法.我们知道,在继承结构中,越往下继承,类会变得越来越明确和具体,而往上回溯,越往上,类会变得越抽象和通用.我们有时候可能会需要这样一 ...
- 常用 php server
php编程中经常需要用到一些服务器的一些资料,我把常用的用高亮的方式贴出来,其余的放在后面.方便以后查阅 复制代码代码如下: $_SERVER['HTTP_ACCEPT_LANGUAGE']/ ...
- Yogurt factory
Description The cows have purchased a yogurt factory that makes world-famous Yucky Yogurt. Over the ...
- 基于NABCD评论探路者团队贪吃蛇作品及改进建议
1.根据(不限于)NABCD评论作品的选题 N:随着人们生活压力越来越大,需要去去缓解压力,并且也需要不断进步,学习英语知识. A:它是基于java开发的一款软件,采用逐个吃字母,加长蛇身,增强记忆的 ...
- 20135208 JAVA第四次实验
课程:Java程序与设计 班级:1352 姓名:贺邦 小组成员: 20135212池彬宁 20135208贺邦 学号:20135208 成绩: 指导教师:娄嘉鹏 ...
- BETA阶段第一天
1.提供当天站立式会议照片一张 2.每个人的工作 今天完成工作 林一心 服务器调试 张杭镖 数据库调整 赵意 前端设计 江鹭涛 前端设计 3.发布项目燃尽图 4.每日每人总结 林一心:服务器端的配置不 ...