BZOJ1002:[FJOI2007]轮状病毒

矩阵树定理大佬题。
要看详细证明看这个:http://vfleaking.blog.163.com/blog/static/17480763420119685112649/
最后化成f[n]=3*f[n-1]-f[n-2]+2的式子
就变成高精度模板题了。emmm

#include <cstdio>
#include <cstring>
using namespace std;
 
int n;
 
int read() {
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0';
    return x*f;
}
 
struct Bignum {
    int num[1000];
 
    void clear() {
        memset(num,0,sizeof(num));
    }
 
    Bignum operator *(const int &a) const {
        Bignum c;c.clear();
        for(int i=1;i<=num[0];i++) {
            c.num[i]+=num[i]*a;
            c.num[i+1]+=c.num[i]/10;
            c.num[i]%=10;
        }c.num[0]=num[0];
        if(c.num[c.num[0]+1])c.num[0]++;
        return c;
    }
     
    Bignum operator -(const Bignum &a) const {
        Bignum c;c=*this;
        for(int i=1;i<=c.num[0];i++) {
            if(c.num[i]<a.num[i])
                c.num[i+1]--,c.num[i]+=10;
            c.num[i]-=a.num[i];
        }
        while(!c.num[c.num[0]])c.num[0]--;
        return c;
    }
     
    Bignum operator +(const int &a) const {
        Bignum c;c=*this;
        for(int i=1;i<=c.num[0];i++) {
            if(i==1)c.num[i]+=a;
            c.num[i+1]+=c.num[i]/10;
            c.num[i]%=10;
        }c.num[0]=num[0];
        return c;
    }
     
    void print() {
        for(int i=num[0];i;i--)
            printf("%d",num[i]);
    }
}f[101];
 
int main() {
    n=read();
    f[1].num[0]=f[1].num[1]=1;
    f[2].num[0]=1,f[2].num[1]=5;
    for(int i=3;i<=n;i++)
        f[i]=f[i-1]*3-f[i-2]+2;
    f[n].print();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Mly020220/p/9497320.html