[luogu2144][bzoj1002][FJOI2007]轮状病毒【高精度+斐波那契数列+基尔霍夫矩阵】
题目描述
轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的。一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道。如下图所示
.png)
N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示
.png)
解法
一开始看到这道题以为是组合数,求\(C^{n-1}_{n+1}\),但是在这个图上可能会出现环,我们需要保证所有的答案都是能够联通所有的点,那么就不能这样做。
那么我们就打一个表,发现答案是斐波那契变形,\(f[i]=f[i-1]\times 3-f[i-2]+2\)。
这道题的公式推导其实是一个生成树计数,其实老实说我真的不会这个东西,但是这篇博客讲的非常非常非常清楚:orz
这道题还需要用到高精度,我的高精度模板是来自网络上的,(不要喷我QwQ)
ac代码
# include <bits/stdc++.h>
# define ms(a,b) memset(a,b,sizeof(a))
# define ri (register int)
# define inf (0x7f7f7f7f)
# define pb push_back
# define fi first
# define se second
# define pii pair<int,int>
# define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
using namespace std;
inline int gi(){
int w=0,x=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
struct BigInteger {
typedef unsigned long long LL;
static const int BASE = 100000000;
static const int WIDTH = 8;
vector<int> s;
BigInteger& clean(){while(!s.back()&&s.size()>1)s.pop_back(); return *this;}
BigInteger(LL num = 0) {*this = num;}
BigInteger(string s) {*this = s;}
BigInteger& operator = (long long num) {
s.clear();
do {
s.push_back(num % BASE);
num /= BASE;
} while (num > 0);
return *this;
}
BigInteger& operator = (const string& str) {
s.clear();
int x, len = (str.length() - 1) / WIDTH + 1;
for (int i = 0; i < len; i++) {
int end = str.length() - i*WIDTH;
int start = max(0, end - WIDTH);
sscanf(str.substr(start,end-start).c_str(), "%d", &x);
s.push_back(x);
}
return (*this).clean();
}
BigInteger operator + (const BigInteger& b) const {
BigInteger c; c.s.clear();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= (int)s.size() && i >= (int) b.s.size()) break;
int x = g;
if (i < s.size()) x += s[i];
if (i < b.s.size()) x += b.s[i];
c.s.push_back(x % BASE);
g = x / BASE;
}
return c;
}
BigInteger operator - (const BigInteger& b) const {
assert(b <= *this);
BigInteger c; c.s.clear();
for (int i = 0, g = 0; ; i++) {
if (g == 0 && i >= s.size() && i >= b.s.size()) break;
int x = s[i] + g;
if (i < b.s.size()) x -= b.s[i];
if (x < 0) {g = -1; x += BASE;} else g = 0;
c.s.push_back(x);
}
return c.clean();
}
BigInteger operator * (const BigInteger& b) const {
int i, j; LL g;
vector<LL> v(s.size()+b.s.size(), 0);
BigInteger c; c.s.clear();
for(i=0;i<s.size();i++) for(j=0;j<b.s.size();j++) v[i+j]+=LL(s[i])*b.s[j];
for (i = 0, g = 0; ; i++) {
if (g ==0 && i >= v.size()) break;
LL x = v[i] + g;
c.s.push_back(x % BASE);
g = x / BASE;
}
return c.clean();
}
BigInteger operator / (const BigInteger& b) const {
assert(b > 0);
BigInteger c = *this;
BigInteger m;
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return c.clean();
}
BigInteger operator % (const BigInteger& b) const {
BigInteger c = *this;
BigInteger m;
for (int i = s.size()-1; i >= 0; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return m;
}
int bsearch(const BigInteger& b, const BigInteger& m) const{
int L = 0, R = BASE-1, x;
while (1) {
x = (L+R)>>1;
if (b*x<=m) {if (b*(x+1)>m) return x; else L = x;}
else R = x;
}
}
BigInteger& operator += (const BigInteger& b) {*this = *this + b; return *this;}
BigInteger& operator -= (const BigInteger& b) {*this = *this - b; return *this;}
BigInteger& operator *= (const BigInteger& b) {*this = *this * b; return *this;}
BigInteger& operator /= (const BigInteger& b) {*this = *this / b; return *this;}
BigInteger& operator %= (const BigInteger& b) {*this = *this % b; return *this;}
bool operator < (const BigInteger& b) const {
if (s.size() != b.s.size()) return s.size() < b.s.size();
for (int i = s.size()-1; i >= 0; i--)
if (s[i] != b.s[i]) return s[i] < b.s[i];
return false;
}
bool operator >(const BigInteger& b) const{return b < *this;}
bool operator<=(const BigInteger& b) const{return !(b < *this);}
bool operator>=(const BigInteger& b) const{return !(*this < b);}
bool operator!=(const BigInteger& b) const{return b < *this || *this < b;}
bool operator==(const BigInteger& b) const{return !(b < *this) && !(b > *this);}
};
ostream& operator << (ostream& out, const BigInteger& x) {
out << x.s.back();
for (int i = x.s.size()-2; i >= 0; i--) {
char buf[20];
sprintf(buf, "%08d", x.s[i]);
for (int j = 0; j < strlen(buf); j++) out << buf[j];
}
return out;
}
istream& operator >> (istream& in, BigInteger& x) {
string s;
if (!(in >> s)) return in;
x = s;
return in;
}
# define N 105
BigInteger f[N];
int main(){
int n = gi ();
f[1]=1; f[2]=5;
for (int i=3;i<=n;i++) f[i]=f[i-1]*3-f[i-2]+2;
cout<<f[n]<<endl;
return 0;
}
[luogu2144][bzoj1002][FJOI2007]轮状病毒【高精度+斐波那契数列+基尔霍夫矩阵】的更多相关文章
- 洛谷——P2626 斐波那契数列(升级版)矩阵
题目背景 大家都知道,斐波那契数列是满足如下性质的一个数列: • f(1) = 1 • f(2) = 1 • f(n) = f(n-1) + f(n-2) (n ≥ 2 且 n 为整数). 题目描述 ...
- HDU1250 高精度斐波那契数列
Hat's Fibonacci Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- poj3070 求斐波那契数列第n项 ——矩阵快速幂
题目:http://poj.org/problem?id=3070 用矩阵快速幂加速递推. 代码如下: #include<iostream> #include<cstdio> ...
- [BSGS算法]纯水斐波那契数列
学弟在OJ上加了道"非水斐波那契数列",求斐波那契第n项对1,000,000,007取模的值,n<=10^15,随便水过后我决定加一道升级版,说是升级版,其实也没什么变化,只 ...
- HDU4549 M斐波那契数列 —— 斐波那契、费马小定理、矩阵快速幂
题目链接:https://vjudge.net/problem/HDU-4549 M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Li ...
- P1349 广义斐波那契数列(矩阵乘法)
题目 P1349 广义斐波那契数列 解析 把普通的矩阵乘法求斐波那契数列改一改,随便一推就出来了 \[\begin{bmatrix}f_2\\f_1 \end{bmatrix}\begin{bmatr ...
- BZOJ1002 FJOI2007 轮状病毒 【基尔霍夫矩阵+高精度】
BZOJ1002 FJOI2007 轮状病毒 Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原 ...
- bzoj 1002 [FJOI2007]轮状病毒 高精度&&找规律&&基尔霍夫矩阵
1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 2234 Solved: 1227[Submit][Statu ...
- bzoj1002: [FJOI2007]轮状病毒(基尔霍夫矩阵)
1002: [FJOI2007]轮状病毒 题目:传送门 题解: 决定开始板刷的第一题... 看到这题的时候想:这不就是求有多少种最小生成树的方式吗? 不会啊!!!%题解... 什么鬼?基尔霍夫矩阵?? ...
随机推荐
- C# 获取电脑MAC地址,IP地址,物理内存,CPU序列号,硬盘ID..........................
上班很忙,自己做个记录 代码如下: 需要引入:System.Management 代码如下: using System; using System.Collections.Generic; using ...
- java.lang.IllegalStateException: Failed to load property source from location 'classpath:/application-dev.yml'
如果你的项目没有配置错误,配置文件名称也正常,还出现这个问题,那一定是你的yml文件编码的问题 先附上一张项目架构图 当我启动服务器寻找配置文件的时候,服务器提示这样的错误信息 java.lang.I ...
- Luogu P4317 花神的数论题
也是一道不错的数位DP,考虑先转成二进制后再做 转化一下问题,考虑统计出\([1,n]\)中在二进制下有\(i\)个\(1\)的方案数\(cnt_i\),那么答案显然就是\(\prod i^{cnt_ ...
- AT3611 Tree MST
题面 题解 考虑最小化\(dis(x, y)\) 这里需要对一种奇怪的最小生成树算法:Boruvka算法有深刻的理解. 考虑该算法的执行过程,我们可以考虑进行点分治,每次找到离分治重心最近的点,然后将 ...
- html table隐藏列
隐藏table表的第一列,适合显示信息,隐藏ID主键. <html> <head> <meta http-equiv="content-type" c ...
- Reactjs-JQuery-Omi-Extjs-Angularjs对比
写在前面 前端越来越混乱了,当然也可以美其名曰:繁荣. 当新启动一个前端项目,第一件事就是纠结:使用什么框架,重造什么轮子? 那么,希望看完此篇,能够给你一个清晰的认识,或者让你更加地纠结和无所适从 ...
- Nagios监控系统部署(源码)
1. 概述2. 部署Nagios2.1 创建Nagios用户组2.2 下载Nagios和Nagios-plugin源码2.3 编译安装3. 部署Nagios-plugin3.1 编译安装nagios- ...
- DRBD详细解说及配置过程记录
一.DRBD介绍 DRBD(Distributed ReplicatedBlock Device)是一种基于软件的,无共享,分布式块设备复制的存储解决方案,在服务器之间的对块设备(硬盘,分区,逻辑卷等 ...
- Python迭代器(Iterator)
概述 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 延迟计算或惰性求值 (Lazy evaluation) 迭代器不要求你 ...
- 矩形A + B HDU2524
题意 给你n*m的棋盘问有多少个矩形 分析 先看只有一行或一列的情况有1+2+....+n个,因为矩形的类型有1个最小单位格子n个,2个最小单位格子n-1个,n个最小单位格子有一个 code #inc ...