BZOJ_1002_[FJOI2007]_轮状病毒(递推+高精)

描述



http://www.lydsy.com/JudgeOnline/problem.php?id=1002

)*&*(^&*^&*^**()*)

分析



题目是求一种特殊的图的生成树的个数,但是貌似有更一般的算法,等明天再看吧...

只搞懂了打表找规律,然后题推的解法.

随便写个暴力打个表(其实我并不会写,明天再写吧今天好累),找一找规律.

1~14的答案如下

1 5 16 45 121 320 841 2205 5776 15125 39601 103680 271441 710645
奇数项
1 16 121 841 5776 39601 271441
开根号得
1 4 11 29 76 199 521
a[i]=a[i-1]*3-a[i-2]
偶数项
5 45 320 2205 15125 103680 710645
除以5得
1 9 64 441 3025 20736 142129
开根号得
1 3 8 21 55 144 377
a[i]=a[i-1]*3-a[i-2]

注意要用高精(学习了别人的高精写法,自己写得太小学生了)

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
struct Big_Integer{
    int x[100],cnt;
    int & operator [] (int id){
        return x[id];
    }
    void operator = (int y){
        x[1]=y;
        cnt=1;
    }
}f[100];
Big_Integer operator - (Big_Integer x,Big_Integer y){
    Big_Integer z=f[0];
    z.cnt=max(x.cnt,y.cnt);
    for(int i=1;i<=z.cnt;i++){
        z[i]+=x[i]-y[i];
        if(z[i]<0) z[i+1]--, z[i]+=10;
    }
    while(z.cnt&&!z[z.cnt]) z.cnt--;
    return z;
}
Big_Integer operator * (Big_Integer x,Big_Integer y){
    Big_Integer z=f[0];
    for(int i=1;i<=x.cnt;i++){
        for(int j=1;j<=y.cnt;j++){
            z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/10,z[i+j-1]%=10;
        }
    }
    z.cnt=x.cnt+y.cnt;
    if(!z[z.cnt]) z.cnt--;
    return z;
}
Big_Integer operator * (Big_Integer x,int y){
    Big_Integer z=f[0];
    for(int i=1;i<=x.cnt;i++){
        z[i]+=x[i]*y,z[i+1]+=z[i]/10,z[i]%=10;
    }
    z.cnt=x.cnt;
    if(z[z.cnt+1]) z.cnt++;
    return z;
}
ostream& operator << (ostream &out,Big_Integer x){
    for(int i=x.cnt;i;i--){
        out << x[i];
    }
    return out;
}
int n;
int main(){
    cin >> n;
    f[1]=1;
    f[2]=n&1?4:3;
    int last=n+1>>1;
    for(int i=3;i<=last;i++){
        f[i]=f[i-1]*3-f[i-2];
    }
    cout << f[last]*f[last]*(n&1?1:5) << endl;
    return 0;
}

时间: 2024-11-14 10:51:23

BZOJ_1002_[FJOI2007]_轮状病毒(递推+高精)的相关文章

BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 110 using namespace std; struct abcd{ int to,next; bool ban; }table[M<<2]; int head[

BZOJ 1002: [FJOI2007]轮状病毒 递推/基尔霍夫矩阵树定理

f[n]=3*f[n-1]-f[n-2]+2 1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2959  Solved: 1644 [Submit][Status][Discuss] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Outpu

BZOJ1002 FJOI2007 轮状病毒 递推

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

luogu P2144 [FJOI2007] 轮状病毒 矩阵(da)生成树(biao)+高精

传送门 明显的生成树 所以矩阵统计完全图的生成树计数就OK ......原地懵逼 并不会行列式 等等 完全图 果断列了一个矩阵(主对角线N*(N-1)/2,其他(N-1)) (当然是3*3矩阵和4*4矩阵) 然后搞了一个互相推 ....30minutes later...... 两个矩阵推不出来 试试三个 (当然是2,3,4) ....20minutes later...... 发现满足f[n] = f[n-1] * 3 - f[n-2] + 2 (鬼知道我是怎么发现的) 1和2可以手胡 然后n

【递推】【高精度】【FJOI 2007】【bzoj 1002】轮状病毒

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3238 Solved: 1797 Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 题解: 递推. 打表可以找规律得,f[i]=3*f[i-1]-f[i-2]+2,但是需要高精

算法分析基础——差消法求解高阶递推方程

差消法,简单来讲,就是对高阶的递推方程作差,转化为一阶方程后再运用迭代法.有了迭代法的基础后,差消法理解起来就很容易了.这里举出对快速排序的分析加以说明. 对于快排,我们知道选择不同的轴值,会导致不同的算法效率.最坏的情况下,选取的轴值恰好是待排序数组的最值,那么排序的效率就会退化为线性时间.现在我们来估算平均情况下快速排序的时间复杂度. 设T(n)为待排序数组长度为n时,快速排序算法需要的比较次数.那么T(1) = 0,而T(n)的递推方程相对于轴值的选取有如下n种情况: T(n) = T(0

数楼梯——恶心的高精斐波那契数列

题目描述 楼梯有N阶,上楼可以一步上一阶,也可以一步上二阶. 编一个程序,计算共有多少种不同的走法. 输入输出格式 输入格式: 一个数字,楼梯数. 输出格式: 走的方式几种. 输入输出样例 输入样例#1: 4 输出样例#1: 5 说明 用递归会太慢,需用递推 (60% N<=50 ,100% N<=5000) 啊啊,数据太大了! 肿么办?! 当数据等于5000时的斐波那契数为 62763028004889570860352531083496840554785287027364574390258

noip推荐系列:遥控车[字符串+高精+二分答案]

[问题描述] 平平带着韵韵来到了游乐园,看到了n辆漂亮的遥控车,每辆车上都有一个唯一的名字name[i].韵韵早就迫不及待地想玩名字是s的遥控车.可是韵韵毕竟还小,她想象的名字可能是一辆车名字的前缀(也就是说能确定一个i,使s是name[i]的前缀),这时她就能玩第i辆车:或者是一个无中生有的名字,即s不是任何一辆车名字的前缀,这时候她什么也不能玩.你需要完成下面的任务: 1.韵韵想了m个她想要的名字,请告诉她能玩多少次. 2.由于管理员粗心的操作,导致每辆车的摆放位置都可能出现微小的差错,原来

[DP][高精][NOIP]Hanoi双塔问题

题目梗概 Hanoi塔问题的基础上,每种圆盘加了一个.实际内容并没有变化. 思考 首先来一波Hanoi问题的步数公式推导: 首先n个不同的圆盘. 只有把n-1个圆盘从a->b,最后把a上剩余的一个圆盘从a->c. 之后把b上的n-1个圆盘从b->c. 这里的两步:把n-1个圆盘从a->c,和n-1个圆盘从b->c.所需要的步骤数.实际上就是把n-1个圆盘从a移动到c的步骤数*2,因为是等价的.从a->b和从b->c移动的圆盘个数都是一样的,所以步数就是 (n-1)