1002: [FJOI2007]轮状病毒 基尔霍夫矩阵

这道题就是求一个图的生成树个数,虽然用基尔霍夫可以做,但是找规律也是找的出来的。

但是还是需要大数。因此在这里放下大数模板和基尔霍夫模板

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-12
#define fi first
#define se second
#define MEM(a,b) memset((a),(b),sizeof(a))
#define mod(x) ((x)%MOD)
#define wz cout<<"-----"<<endl;
#define pb push_back
#define mp make_pair
#define pll pair <LL, LL>
#define pii pair <int, int>
#define rep(i,x) for(int i=1;i<=x;i++)
const int INF_INT = 2147483647;
const ll INF_LL = 9223372036854775807LL;
const ull INF_ULL = 18446744073709551615Ull;
const ll P = 92540646808111039LL;
 
const ll maxn = 1e5 + 10, MOD = 1e9 + 7;
const int Move[4][2] = {-1,0,1,0,0,1,0,-1};
const int Move_[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
 
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int N=1e4+5;
int n;
struct Bigint{
    int size,num[N];
    void init(int d){
        int s=0;
        while(d){
            s++;num[s]=d%10;
            d/=10;
        }size=s;
    }
    void print(){
        for(int i=size;i>=1;i--)printf("%d",num[i]);
        printf("
");
    }
    void clear(){
        for(int i=1;i<=size;i++)num[i]=0;
    }
    
};
Bigint operator +(const Bigint &a,const Bigint &b){
    Bigint ans;
    ans.size=max(a.size,b.size)+1;
    ans.clear();
    for(int i=1;i<=ans.size;i++){
        ans.num[i]=a.num[i]+b.num[i];
    }
    for(int i=1;i<ans.size;i++){
        ans.num[i+1]+=ans.num[i]/10;
        ans.num[i]%=10;
    }
    while(!ans.num[ans.size])ans.size--;
    return ans;
}
Bigint operator - (const Bigint & a, const Bigint & b) {
    
    Bigint ans; int s = max(a.size, b.size);
    ans.clear( );
    for(int i = 1;i <= s;i ++) {
        ans.num[i] = a.num[i] - b.num[i];
        if(ans.num[i] < 0) {
            ans.num[i + 1] --; ans.num[i] += 10;
        }
    }
    while(! ans.num[s]) s --; ans.size = s;
    return ans;
}
Bigint operator * (const Bigint & a, const Bigint & b) {
    
    Bigint ans; int s1 = a.size, s2 = b.size;
    int s = a.size + b.size - 1;
    ans.clear( );
    for(int i = 1;i <= s1;i ++)
        for(int j = 1;j <= s2;j ++)
            ans.num[i + j - 1] += a.num[i] * b.num[j];
    int k = 1;
    while(ans.num[k] || k <= s) {
        ans.num[k + 1] += ans.num[k] / 10;
        ans.num[k] %= 10;
        k ++;
    }
    while(ans.num[k] == 0) k --;
    ans.size = k;
    return ans;
}
int main(){
    n=read();
    Bigint a,b,c;
    a.init(1),b.init(3),c.init(4);
    for(int i=3;i<=n;i++){
        if(i%2)a=a+b;
        else b=a+b;
    }
    if(n%2){
        a=a*a,a.print();
    }else{
        b=b*b-c;b.print();
    }
    return 0;
    
}
View Code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define LL long long
#define ull unsigned long long
#define PI acos(-1.0)
#define eps 1e-12
#define fi first
#define se second
#define MEM(a,b) memset((a),(b),sizeof(a))
#define mod(x) ((x)%MOD)
#define wz cout<<"-----"<<endl;
#define pb push_back
#define mp make_pair
#define pll pair <LL, LL>
#define pii pair <int, int>
#define rep(i,x) for(int i=1;i<=x;i++)
const int INF_INT = 2147483647;
const ll INF_LL = 9223372036854775807LL;
const ull INF_ULL = 18446744073709551615Ull;
const ll P = 92540646808111039LL;
 
const ll maxn = 1e5 + 10, MOD = 1e9 + 7;
const int Move[4][2] = {-1,0,1,0,0,1,0,-1};
const int Move_[8][2] = {-1,-1,-1,0,-1,1,0,-1,0,1,1,-1,1,0,1,1};
 
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int M=150;
int degree[M];
ll a[M][M];
int n;
ll det(int n){
    //计算行列式 
    ll ret=1;
    for(int i=2;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            while(a[j][i]){
                ll t=a[i][i]/a[j][i];//如果取模就搞这 
                for(int k=i;k<=n;k++){
                    a[i][k]=(a[i][k]-a[j][k]*t);
                }
                for(int k=i;k<=n;k++){
                    swap(a[i][k],a[j][k]);
                }
                ret=-ret;
            }
        }
        if(a[i][i]==0)return 0;
        ret*=a[i][i];
    }
    if(ret<0)ret=-ret;
    return ret;
}
int main(){
    //a[i][i]是本身的度数,a[i][j]是i和j的连边个数,记得是减。 
    cout<<det(n)<<endl;
    return 0;
    
}
View Code
原文地址:https://www.cnblogs.com/Ean1zhi/p/14140199.html