【题目描述】

给定n(N<=100),编程计算有多少个不同的n轮状病毒。

【输入格式】

第一行有1个正整数n。

【输出格式】

将编程计算出的不同的n轮状病毒数输出

【样例输入】

3

【样例输出】

16

【题目来源】

耒阳大世野(衡阳八中) OJ 1002

(福建省选赛2007)

【分析】

从“各原子有唯一的信息通道”不难看出,每种轮状病毒对应着轮状基的一棵生成树。一般图的生成树计数可以用Matrix-Tree 定理求解,但这里的图比较特殊,用Matrix-Tree未免有些小题大做, 我们可以用组合递推的方法求解。

先设$f(n)$为n轮状基上删去一条弧得到的“缺口轮”上的生成树个数,再设$S(n) = \sum \limits_{i = 1}^n {f(i)}$. 于是就有:

$$\begin{array}{F} f(0) = f(1) = 1\\ f(n) = 2f(n-1) + \sum_{i=0}^{n-2} f(i) = f(n-1) + S(n-1) + 1 \end{array}$$

$$ans(n) = f(n) + 2\sum_{i = 1}^{n-1}f(i) = S(n) + S(n-1)$$

    (这个公式我推了一上午我会说?)

考虑到n最大为100,答案会超过long long的范围,这里的状态值应用高精度类存储。

 1 /**************************************************************
 2     Problem: 1002
 3     User: 935671154
 4     Language: C++
 5     Result: Accepted
 6     Time:44 ms
 7     Memory:2068 kb
 8 ****************************************************************/
 9  
 //Author : Asm.Def
 #include <iostream>
 #include <cctype>
 #include <cstdio>
 #include <vector>
 #include <algorithm>
 #include <cmath>
 #include <queue>
 using namespace std;
 inline void getd(int &x){
     char c = getchar();
     bool minus = ;
     while(!isdigit(c) && c != '-')c = getchar();
     if(c == '-')minus = , c = getchar();
     x = c - '';
     while(isdigit(c = getchar()))x = x *  + c - '';
     if(minus)x = -x;
 }
 /*======================================================*/
 const int maxn = ;
  
 struct BigN{
     #define base 10000
     #define maxl 1000
     int A[maxl], len;
     BigN(){len = , A[] = ;}
     BigN &operator = (const BigN &x){
         len = ;
         while(len < x.len){A[len] = x.A[len]; ++len;}
         return *this;
     }
     BigN &operator = (int k){len = ;A[] = k; return *this;}
     BigN &operator += (const BigN &x){
         int i, mor = ;
         for(i = ;i < x.len || mor;++i){
             if(i < len)mor += A[i];
             if(i < x.len)mor += x.A[i];
             A[i] = mor % base;
             mor /= base;
         }
         if(i > len)len = i;
         return *this;
     }
 }f[maxn], S[maxn];
  
 inline void work(int k){
     int i;
     if(!k){printf("0\n");return;}
     f[] = , f[] = , S[] = ;
     if(k == ){printf("1\n");return;}
     for(i = ;i <= k;++i){
         f[i] = ; f[i] += f[i-]; f[i] += S[i-];
         S[i] = S[i-]; S[i] += f[i];
     }
     S[k] += S[k-];
     i = S[k].len - ;
     printf("%d", S[k].A[i]);
     while(i)
         printf("%04d", S[k].A[--i]);
     putchar('\n');
 }
      
 int main(){
     #if defined DEBUG
     freopen("test", "r", stdin);
     #endif
     int k;
     getd(k);
      
     work(k);
      
     #if defined DEBUG
     cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
     #endif
     return ;
 }

高精度 + 递推

[BZOJ1002](FJOI 2007) 轮状病毒的更多相关文章

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

    题目大意: 思路:基尔霍夫矩阵求生成树个数,不会. 可是能够暴力打表.(我才不会说我调试force调试了20分钟... CODE(force.cc): #include <cstdio> ...

  2. 【BZOJ1002】[ZJOI2006]轮状病毒

    [BZOJ1002]轮状病毒 题面 bzoj 题解 统计个数显然直接矩阵树定理,找规律截这里 打标如下: #include <iostream> #include <cstdlib& ...

  3. 【BZOJ1002】[FJOI2007]轮状病毒 递推+高精度

    Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Inpu ...

  4. 【bzoj1002】[FJOI2007]轮状病毒

    1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4381  Solved: 2393[Submit][Statu ...

  5. 【bzoj1002】[FJOI2007]轮状病毒 矩阵树定理+高精度

    题目描述 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病 ...

  6. BZOJ 1002 [ FJOI 2007 ]

    -------------------------萌萌哒分割线------------------------- 题目很容易看懂,数据范围也不大.当然可以卡过暴力的人了. 在n=1时很明显是一种,如下 ...

  7. bzoj1002:[FJOI2007]轮状病毒

    思路:一道很裸的生成树计数问题,然而要高精度,而且听说直接行列式求值会被卡精度,所以可以模拟行列式求值的过程得到递推公式:f[i]=3*f[i-1]-f[i-2]+2,证明详见vfk博客: http: ...

  8. 【bzoj1002】 [FJOI2007]轮状病毒DP

    递推+环状特殊处理+高精度   #include<algorithm> #include<iostream> #include<cstdlib> #include& ...

  9. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

随机推荐

  1. Android开发中的各种尺度单位

    px 像素(pixel),表示屏幕上一个物理像素点 不建议直接使用 px 绘制UI,因为受像素密度的影响,以 px 为单位绘制的UI在不同手机上显示的实际大小会不同 dp   (用于定义控件大小) 密 ...

  2. python--数据持久化

    python中与数据持久化有关的模块有很多,像pickle.json之类的就不介绍了,这里介绍两个其他的模块:dbm和shelve 1.dbm ''' 在一些小型程序中,不需要关系型数据库时,可以方便 ...

  3. Eclipse+Pydev+numpy+scipy+matplotlib

    之前一直在linux环境下使用python,作为一枚小菜还是更喜欢windows.我使用python主要是进行科学计算,安装软件.搭建环境遇到了非常多的问题,特此总结. 一.python安装 版本:2 ...

  4. 7:django 中间件

    中间件 中间件是一个连接django请求/相应处理的框架,是一个轻量级的低层次的全局影响django输入输出的系统插件. 每一个中间件组件负责一些特定的功能,这里我们我们只看一下如何激活使用系统自带的 ...

  5. 外部div不能包裹内部div的问题

    转自http://www.du52.com/text.php?id=362 当设计网页时,如果内部div全部设置css属性float为左右浮动,那么外部div将不能包裹内部div 解决方法 1.在内部 ...

  6. maven新建web项目提示The superclass "javax.servlet.http.HttpServlet" was not found on the Java Build Path

    maven新建web项目提示The superclass "javax.servlet.http.HttpServlet" was not found on the Java Bu ...

  7. ES6新数据结构Set让数组去重

    function unique(array){ return Array.from(new Set(array)); } var arr = ['aa','bb','cc','',1,0,'1',1, ...

  8. IOS中div contenteditable=true无法输入 fastclick.js在点击一个可输入的div时,ios无法正常唤起输入法键盘

    原文地址: https://blog.csdn.net/u010377383/article/details/79838562 前言 为了提升移动端click的响应速度,使用了fastclick.js ...

  9. 深入理解String.intern()方法

    首先进入intern()的源码中, 首先说一点:1.7后的JVM为String在方法区中开辟了一个字符串常量池,如果一个String()不是new()出来的,都将在常量池中拿字符. 注释翻译过来就是, ...

  10. 【转载】LinearLayout 源码分析

    原文地址:https://github.com/razerdp/AndroidSourceAnalysis/blob/master/LinearLayout/android_widget_Linear ...