bzoj1002轮状病毒

这题正解基尔霍夫矩阵(本蒟蒻不会)

于是就找规律吧。

前7项答案为

1 5 16 45 121 320 841

其实可以看成

1*1  3*3-4  4*4  7*7-4  11*11  18*18-4  29*29

4=3+1,7=4+3,11=7+4...

就是一个Fibonacci 第一项为1,第二项为3

F[n]=f(n)^2-4*(1-n%2);

再加个高精度就完了。

(Ps:懒得打高精度减了,直接减了4)

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 using namespace std;
 5 const int mod=10000;
 6 int n;
 7 struct Bign {
 8     int len,s[105];
 9     Bign() {
10         memset(s,0,sizeof(s));
11         len=1;
12     }
13     void Zore() {
14         while (len&&!s[len]) len--;
15     }
16     void print() {
17         if (!(n&1)) s[1]-=4;
18         printf("%d",s[len]);
19         for (int i=len-1;i;i--) printf("%04d",s[i]);
20     }
21 }f[105],x;
22
23 Bign add(Bign a,Bign b) {
24     for (int i=1;i<=b.len;i++) b.s[i]+=a.s[i];
25     for (int i=1;i<=b.len;i++) b.s[i+1]+=b.s[i]/mod,b.s[i]%=mod;
26     while (b.s[b.len+1]) ++b.len;
27     return b;
28 }
29 Bign mul(Bign a,Bign b) {
30     Bign c;c.len=a.len+b.len+2;
31     for (int i=1;i<=b.len;i++)
32         for (int j=1;j<=a.len;j++)
33             c.s[i+j-1]+=a.s[i]*b.s[j];
34     for (int i=1;i<=c.len;i++) c.s[i+1]+=c.s[i]/mod,c.s[i]%=mod;
35     while (c.s[c.len+1]) ++c.len;
36     c.Zore();
37     return c;
38 }
39
40 int main()
41 {
42     scanf("%d",&n);
43     f[1].s[1]=1;f[1].len=1;f[2].s[1]=3;f[2].len=1;
44     for (int i=3;i<=n;i++) f[i]=add(f[i-2],f[i-1]);
45     x=mul(f[n],f[n]);
46     x.print();
47     return 0;
48 }

时间: 2024-10-14 12:09:03

bzoj1002轮状病毒的相关文章

BZOJ1002 轮状病毒

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

bzoj1002 轮状病毒 暴力打标找规律/基尔霍夫矩阵+高斯消元

基本思路: 1.先观察规律,写写画画未果 2.写程序暴力打表找规律,找出规律 1-15的答案:1    5    16    45    121 320 841     2205   5776 15125 39601  103680  271441    710645      1860496 第1.3.5.7...[奇数位]位是平方数 : 1*1  4*4  11*11   29*29   76*76   199*199  521*521... 第2.4.6.8...[偶数位]位除以5后也是平

bzoj1002[FJOI2007]轮状病毒

bzoj1002[FJOI2007]轮状病毒 题意: N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示 现给定n,计算有多少个不同的n轮状病毒.N<=100 题解: 公式:f[i]=f[i-1]*3-f[i-2]+2,i≥3,f[1]=1,f[2]=5.(我承认我是抄的QAQ因为我根本不懂什么矩阵树定理~ 又是高精度,又被我用python水掉了…… 代码: 1 n=int(raw_input()) 2 a=1 3 b=

[BZOJ1002] [FJOI2007] 轮状病毒 (基尔霍夫矩阵)

Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 HINT Source Solution 基尔霍夫矩阵,左转生成树的计数及其应用 推出本题的递推式:f[n] = f[n - 1] * 3 - f[n - 2] + 2 如果你能看懂,拜托给我讲讲,本人不懂. 注意要使用高精度 1 #include <cstri

[bzoj1002][FJOI2007]轮状病毒-题解[基尔霍夫矩阵][高精度][递推]

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

[bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)

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

【bzoj1002】【FJOI2007】【轮状病毒】

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3060 Solved: 1695 [Submit][Status][Discuss] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 思路:其实就是一道递推的题. 开始我本来

BZOJ1002 FJOI2007 轮状病毒 递推

题意:给定一个轮状结构(中间一个点,周围有N个点以环状围住这个点),从不相交的2*N-1条边中选N条边,使任意两点间有且只有一条联通路径. 题解:请点这里.然而如果考场上考到直接打表找规律好了 #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int

【BZOJ1002】【FJOI2007】轮状病毒 生成树计数推导。 Python代码

突然学了一小下Python 算是勉强会写点了. 至于这道题的题解,就是根据Matrix Tree定理,然后Kirchhoff矩阵高斯消元就好了, 不过这道题如果消去中心点的行和列做的话,矩阵会很规矩,然后貌似"手算"可以推出公式(VFK Orz,手算--) VFK's blog:http://vfleaking.blog.163.com/blog/static/17480763420119685112649/ 然后下面是Python代码,算是裸语法吧. n=int(raw_input(