BZOJ 1002 FJOI 2007 轮状病毒 暴力+找规律+高精度

题目大意:

思路:基尔霍夫矩阵求生成树个数,不会。

但是可以暴力打表。(我才不会说我调试force调试了20分钟。。。

CODE(force.cc):

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000
using namespace std;

struct Edge{
	int x,y;

	Edge(int _,int __):x(_),y(__) {}
	Edge() {}
}edge[MAX];

int edges;
int status;

int father[MAX];

int Find(int x)
{
	if(father[x] == x)	return x;
	return father[x] = Find(father[x]);
}

inline bool Unite(int x,int y)
{
	int fx = Find(x);
	int fy = Find(y);
	if(fx != fy) {
		father[fx] = fy;
		return true;
	}
	return false;
}

int main()
{
	for(int i = 1; i <= 20; ++i) {
		edges = 0;
		for(int j = 1; j <= i; ++j)
			edge[++edges] = Edge(0,j);
		for(int j = 1; j < i; ++j)
			edge[++edges] = Edge(j,j + 1);
		edge[++edges] = Edge(i,1);
		int ans = 0;
		for(int j = 1; j <= (1 << edges); ++j) {
			int added = 0;
			for(int k = 0; k <= i; ++k)
				father[k] = k;
			for(int k = 0; k < edges; ++k)
				added += (j >> k)&1;
			if(added  != i)	continue;
			added = 0;
			for(int k = 0; k < edges; ++k)
				if((j >> k)&1)
					added += Unite(edge[k + 1].x,edge[k + 1].y);
			ans += (added == i);
		}
		cout << i << ':' << ans << endl;
	}
	return 0;
}

打出的表是这样的。。

后面的数太大了爆了。。

很明显可以看出奇数的数都是完全平方数。把它们开跟,然后经过艰苦卓绝的分析之后,得到了一个递推式:

f[i] = f[i - 1] + Σf[j] + 2 (j∈[1,i - 1]),答案是f[n] ^ 2

有了这个结论,偶数的就好办了。可以看到,偶数的除以5之后也是完全平方数,和上面很像,它的递推式是:

f[i] = f[i - 1] + Σf[j] + 1 (j∈[i,i - 1]),答案是f[n] ^ 2 * 5

至于为什么递推式长这样,谜。

CODE:

#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define BASE 10000
#define MAX 1010
using namespace std;

struct BigInt{
	int num[MAX],len;

	BigInt(int _ = 0) {
		memset(num,0,sizeof(num));
		len = _ ? 1:0;
		num[1] = _;
	}
	BigInt operator +(const BigInt &a)const {
		BigInt re;
		re.len = max(len,a.len);
		int temp = 0;
		for(int i = 1; i <= re.len; ++i) {
			re.num[i] = num[i] + a.num[i] + temp;
			temp = re.num[i] / BASE;
			re.num[i] %= BASE;
		}
		if(temp)	re.num[++re.len] = temp;
		return re;
	}
	BigInt operator *(const BigInt &a)const {
		BigInt re;
		for(int i = 1; i <= len; ++i)
			for(int j = 1; j <= a.len; ++j) {
				re.num[i + j - 1] += num[i] * a.num[j];
				re.num[i + j] += re.num[i + j - 1] / BASE;
				re.num[i + j - 1] %= BASE;
			}
		re.len = len + a.len;
		if(!re.num[re.len])	--re.len;
		return re;
	}
};

ostream &operator <<(ostream &os,const BigInt &a)
{
	os << a.num[a.len];
	for(int i = a.len - 1; i; --i)
		os << fixed << setw(4) << setfill('0') << a.num[i];
	return os;
}

int k;
BigInt f[110],g[110];

int main()
{
	cin >> k;
	if(k&1) {
		k = (k + 1) >> 1;
		f[1] = BigInt(1),f[2] = BigInt(4);
		g[1] = BigInt(1),g[2] = BigInt(5);
		for(int i = 3; i <= k; ++i) {
			f[i] = f[i - 1] + g[i - 1] + BigInt(2);
			g[i] = g[i - 1] + f[i];
		}
		cout << f[k] * f[k] << endl;
	}
	else {
		k >>= 1;
		f[1] = BigInt(1),f[2] = BigInt(3);
		g[1] = BigInt(1),g[2] = BigInt(4);
		for(int i = 3; i <= k; ++i) {
			f[i] = f[i - 1] + g[i - 1] + BigInt(1);
			g[i] = g[i - 1] + f[i];
		}
		cout << f[k] * f[k] * BigInt(5) << endl;
	}
	return 0;
}
时间: 2024-12-25 19:31:51

BZOJ 1002 FJOI 2007 轮状病毒 暴力+找规律+高精度的相关文章

[BZOJ 1002] [FJOI 2007] 轮状病毒

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3045  Solved: 1687[Submit][Status][Discuss] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 [题解] 我就一个蒟蒻写什么题解呢= =

BZOJ 1002 [ FJOI 2007 ]

-------------------------萌萌哒分割线------------------------- 题目很容易看懂,数据范围也不大.当然可以卡过暴力的人了. 在n=1时很明显是一种,如下 在n=2时候,有5种(有人认为是三种,上图澄清一下) 事实上,很容易看出递推可以解决这个问题 选择一种情况..比如(2-轮状病毒)第一种 插入一个点.. 如何推到(3-轮状病毒)的几种情况呢? 这是比较理想的情况.而

[FJOI2007]轮状病毒 题解(dp(找规律)+高精度)

[FJOI2007]轮状病毒 题解(dp(找规律)+高精度) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1335733 没什么好说的,直接把规律找出来,有两种规律(据说还有多种dp),再套个高精度 \(First\) \(f[1]=1,f[2]=5,f[i]=3×f[i-1]-f[i-2]+2\) 就直接写个高精+低精和高精×低精和高精-高精就行了 \(Second\) \(f[1]=1,f[2]=3,f[i]=f[i-1]+f[i-2]\) \(i

Codeforces 57C Array dp暴力找规律

题目链接:点击打开链接 先是计算非递增的方案, 若非递增的方案数为x, 则非递减的方案数也是x 答案就是 2*x - n 只需求得x即可. 可以先写个n3的dp,然后发现规律是 C(n-1, 2*n-1) 然后套个逆元即可. #include<iostream> #include<cstdio> #include<vector> #include<string.h> using namespace std; #define ll long long #def

HDU 5351 MZL&#39;s Border(找规律+高精度)

MZL's Border Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 895    Accepted Submission(s): 287 Problem Description As is known to all, MZL is an extraordinarily lovely girl. One day, MZL was p

1002. [FJOI2007]轮状病毒【找规律+递推】

Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子 和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不 同的3轮状病毒,如下图所示 现给定n(N<=100),编程计算有多少个不同的n轮状病毒 Input 第一行有1个正整数n Output 计算出的不同的n轮状病毒数输出 Sample Inpu

ACM_同余+暴力找规律

小光的忧伤 Time Limit: 2000/1000ms (Java/Others) Problem Description: 锴神:我尊重作者原意,你们出什么我就加什么.于是小光打了道水题(也就是这道),但是呢比赛的时候拿着自己的标程却AC不了,最后只能尴尬地打表!!为毛呢?!请你来看看这道题,为了缓解小光的尴尬,他决定不告诉你样例输入输出,神马?!没有输入输出?对,就是这么贼! Input: 多组数据,输入n,求(1^n+2^n+3^n+4^n)mod 5,其中n范围是[10^5,10^(

BZOJ 1228 E&amp;G(sg函数+找规律)

把一对石子堆看出一个子游戏.打出子游戏的sg表找规律.. 这个规律我是一定找不出来的... 对于i,j,如果 (i-1)%pow(2,k+1) < pow(2,k) (j-1)%pow(2,k+1) < pow(2,k) 那么最小的k值就是sg值. # include <cstdio> # include <cstring> # include <cstdlib> # include <iostream> # include <vector

bzoj 1002 [FJOI2007]轮状病毒 高精度&amp;&amp;找规律&amp;&amp;基尔霍夫矩阵

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2234  Solved: 1227[Submit][Status] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 HINT Source 基尔霍夫矩阵总算编出来了,这道题考