zoukankan      html  css  js  c++  java
  • 1002: [FJOI2007]轮状病毒

    题目链接:

    题意:就是给出n,表示有n+1个点通过n条边相连。求一共有多少种连法!总的来说就是求生成树的个数有多少种

    这是一篇大佬的题解:

    其实说了一大堆就是证明了f[i]=3f[i-1]-f[i-2]+2。这个就是本题的递推式

    而这个怎么来的?大佬的证明说明了一个基尔霍夫矩阵的任一余子式的行列式的值就是该图的生成树的个数 

    所以我们就可以通过对余子式做代数余子式的展开求行列式的方法,就可以推出上面那个公式,不会推就记住好了(反正我觉得我就算现在会推过几天就忘了emmm)

    本题虽然最大数据只有100,但是还是顶不住爆ll,所以要写个高精度加法跟减法,那个乘法相当于加三次(我不想敲高精度乘法,主要是不太会)

    #include <set>
    #include <map>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <string>
    #include <sstream>
    #include <algorithm>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <iostream>
    #include <functional>
    using namespace std;
    #define ll long long
    #define fi first
    #define se second
    #define re register
    #define pb push_back
    void read(int &a)
    {
        a=0;
        int d=1;
        char ch;
        while(ch=getchar(),ch>'9'||ch<'0')
            if(ch=='-')
                d=-1;
        a=ch-'0';
        while(ch=getchar(),ch>='0'&&ch<='9')
            a=a*10+ch-'0';
        a*=d;
    }
    void write(int x)
    {
        if(x<0)
            putchar(45),x=-x;
        if(x>9)
            write(x/10);
        putchar(x%10+'0');
    }
    string f[105];
    string add(string st1,string st2)
    {
        string str;
        int d=0;
        int len1=st1.length();
        int len2=st2.length();
        if(len1>len2)
            for(re int i=0;i<len1-len2;i++)
                st2='0'+st2;
        else
            for(re int i=0;i<len2-len1;i++)
                st1='0'+st1;
        for(re int i=st1.size()-1;i>=0;i--)
        {
            int a,b;
            a=st1[i]-'0';
            b=st2[i]-'0';
            a=a+b+d;
            d=a/10;
            str=char(a%10+'0')+str;
        }
        if(d!=0)  str=char(d+'0')+str;
        return str;
    }
    string solve(int x)
    {
        string s="";
        do
        {
            s.pb(x%10);
            x/=10;
        }while(x);
        reverse(s.begin(),s.end());
        return s;
    }
    string sub(string st1,string st2)
    {
        string tem;
        int d=0;
        bool f=true;
        int len1=st1.length();
        int len2=st2.length();
        if(len1<len2||(len1==len2&&st1<st2))
        {
            string t=st1;
            st1=st2;
            st2=t;
            int tt=len1;
            len1=len2;
            len2=tt;
            f=false;
        }
        else if(len1==len2&&st1==st2)
        {
            tem='0';
            return tem;
        }
        for(re int i=1;i<=len1-len2;i++)
            st2='0'+st2;
        for(re int i=len1-1;i>=0;i--)
        {
            int t=(st1[i]-'0')-(st2[i]-'0')-d;
            if(t<0)
            {
                t+=10;
                d=1;
            }
            else
                d=0;
            tem=char(t+'0')+tem;
        }
        if(tem.size()==1)
        {
            if(!f)
                tem='-'+tem;
            return tem;
        }
        while(1)
        {
            if(tem[0]=='0')
                tem.erase(0,1);
            else
                break;
        }
        if(!f)
            tem='-'+tem;
        return tem;
    }
    int main()
    {
        int n;read(n);
        string st1,st2;
        f[1]="1",f[2]="5";
        st1=solve(n);st2=solve((n+1)*n);
        for(re int i=3;i<=n;i++)
        {
            for(re int j=1;j<=3;j++) f[i]=add(f[i],f[i-1]);
            f[i]=add(f[i],"2");
            f[i]=sub(f[i],f[i-2]);
        }
        cout<<f[n]<<endl;
        return 0;
    }
  • 相关阅读:
    spring 配置详解
    SpringBoot 快速整合Mybatis(去XML化+注解进阶)
    Spring Boot Mvc 单元测试
    Connect to DB2 database in eclipse via jdbc
    spring boot 学习
    小程序扫描普通链接二维码跳转小程序指定界面
    开启MySQL远程访问权限 允许远程连接
    JS概述
    全然用linux工作,放弃windows
    FarPoint.Win.Spread 常规操作
  • 原文地址:https://www.cnblogs.com/acm1ruoji/p/12019327.html
Copyright © 2011-2022 走看看