【bzoj1002】轮状病毒

Portal-->bzoj1002

Solution

  虽然说看上去是一道矩阵树定理的题但是

  但是!

  没有模数了解一下,\(n=100\)了解一下

  开心愉快敲了一个高消之后发现跑到\(80\)都已经炸了

  果断放弃了高消写高精度的念头之后突然发现好像这堆矩阵长的都差不多啊

  然后就开始大力打表找规律了。。。

  最后发现其实如果用\(f[x]\)表示\(n=x\)时的答案,那么我们有:

\[f[n]=3*f[n-1]-f[n-2]+2 \]

  然后就高精度一下就好了

  就是这么冷酷无情并且虚伪qwq

  

  代码大概长这个样子

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=110;
struct bint{/*{{{*/
    int a[N+1];
    void set(int val){
        memset(a,0,sizeof(a));
        a[N]=val;
    }
    friend bint operator * (bint x,int y){
        bint ret; ret.set(0);
        int s,g=0;
        for (int i=N;i>=1;--i){
            s=x.a[i]*y+g;
            ret.a[i]=s%10;
            g=s/10;
        }
        return ret;
    }
    friend bint operator - (bint x,bint y){
        bint ret; ret.set(0);
        int s,g=0;
        for (int i=N;i>=1;--i){
            if (x.a[i]-g-y.a[i]>=0)
                ret.a[i]=x.a[i]-g-y.a[i],g=0;
            else
                ret.a[i]=x.a[i]+10-g-y.a[i],g=1;
        }
        return ret;
    }
    friend bint operator + (bint x,bint y){
        bint ret; ret.set(0);
        int s,g=0;
        for (int i=N;i>=1;--i){
            s=x.a[i]+y.a[i]+g;
            ret.a[i]=s%10;
            g=s/10;
        }
        return ret;
    }
    void print(){
        int j=1;
        while (a[j]==0) ++j;
        for (int i=j;i<=N;++i) printf("%d",a[i]);
        printf("\n");
    }
}f[N],two;/*}}}*/
int n;
 
int main(){
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
#endif
    scanf("%d",&n);
    f[1].set(1);
    f[2].set(5);
    two.set(2);
    for (int i=3;i<=n;++i)
        f[i]=f[i-1]*3-f[i-2]+two;
    f[n].print();
}
posted @ 2018-06-25 21:41  yoyoball  阅读(392)  评论(0编辑  收藏  举报