bzoj1002-[FJOI2007]轮状病毒

本文探讨了基尔霍夫矩阵在计算最小生成树计数中的应用,通过递推公式f_i=3*f_{i-1}

基尔霍夫矩阵求最小生成树计数.

之后打表发现

\[ f_1 = 1, f_2 = 5 \]
\[ f_i = 3 * f_{i-1} - f_{i-2} + 2 (i \ge 3) \]

证明见vfk大爷的博客.

高精度模拟即可.

另外,注意高精度输出时前面要补0,详见代码.

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
using namespace std;
#define rep(i,l,r) for(register int i=(l);i<=(r);++i)
#define repdo(i,l,r) for(register int i=(l);i>=(r);--i)
#define il inline
typedef double db;
typedef long long ll;

//---------------------------------------
const int nsz=105;
int n;
const int nbl=100,bsz=10000;
struct tbig{
    int val[nbl];
    void set(int v){
        val[0]=0;
        for(;v;v/=bsz){
            val[++val[0]]=v%bsz;
        }
    }
    void pr(){
        printf("%d",val[val[0]]);
        repdo(i,val[0]-1,1)printf("%04d",val[i]); //important
    }
}dp[nsz],v2;
tbig sub(tbig a,tbig b){//a-b+2
    a.val[1]+=2;
    rep(i,1,a.val[0]){
        if(a.val[i]<bsz)break;
        a.val[i]-=bsz,a.val[i+1]+=1;
    }
    rep(i,1,a.val[0]){
        a.val[i]-=b.val[i];
        if(a.val[i]<0)a.val[i]+=bsz,--a.val[i+1];
    }
    if(a.val[a.val[0]]==0)--a.val[0];
    return a;
}
tbig mul(tbig a,int b){//a*b
    rep(i,1,a.val[0]){
        a.val[i]*=b;
    }
    rep(i,1,a.val[0]){
        if(a.val[i]>bsz)a.val[i+1]+=a.val[i]/bsz,a.val[i]%=bsz;
    }
    while(a.val[a.val[0]+1])++a.val[0];
    return a;
}
int main(){
//  ios::sync_with_stdio(0),cin.tie(0);
    cin>>n;
    v2.set(-2);
    dp[1].set(1),dp[2].set(5);
    rep(i,3,n){
        dp[i]=sub(mul(dp[i-1],3),dp[i-2]);
    }
    dp[n].pr();
    putchar('\n');
    return 0;
}

转载于:https://www.cnblogs.com/ubospica/p/9808975.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值