zoukankan      html  css  js  c++  java
  • BZOJ 4031: [HEOI2015]小Z的房间 (矩阵树定理 板题)

    背结论 : 度-邻

    CODE1

    O(n3logn)O(n^3logn)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    template<class T>inline void read(T &num) {
        register char ch; register int flg = 1;
        while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
        for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar());
        num *= flg;
    }
    const int MAXN = 85;
    const int mod = 1e9;
    int n, m, tot, id[10][10];
    int a[MAXN][MAXN], d[MAXN][MAXN], g[MAXN][MAXN];
    char s[10];
    inline void link(int u, int v) {
        ++d[u][u], ++d[v][v];
        ++g[u][v], ++g[v][u];
    }
    inline int Gauss(int N) { //高斯消元成上三角
        int ans = 1;
        for(int i = 1; i <= N; ++i) {
            for(int k = i+1; k <= N; ++k)
                while(a[k][i]) { //这里有一个log
                    int d = a[i][i] / a[k][i];
                    for(int j = i; j <= N; ++j)
                        a[i][j] = ((a[i][j] - 1ll * d * a[k][j] % mod) % mod + mod) % mod;
                    swap(a[i], a[k]), ans = -ans; //注意每交换两行都要取反
                }
            ans = (1ll * ans * a[i][i] % mod + mod) % mod;
        }
        return ans;
    }
    int main() {
        read(n), read(m);
        for(int i = 1; i <= n; ++i) {
            scanf("%s", s+1);
            for(int j = 1; j <= m; ++j)
                if(s[j] != '*') {
                    id[i][j] = ++tot;
                    if(id[i-1][j]) link(tot, id[i-1][j]);
                    if(id[i][j-1]) link(tot, id[i][j-1]);
                }
        }
        for(int i = 1; i < tot; ++i)
            for(int j = 1; j < tot; ++j)
                a[i][j] = d[i][j] - g[i][j];
        printf("%d
    ", (Gauss(tot-1) + mod) % mod);
    }
    
    

    CODE2

    O(n3+n2logn)O(n3)O(n^3+n^2logn) o O(n^3)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    template<class T>inline void read(T &num) {
        register char ch; register int flg = 1;
        while(!isdigit(ch=getchar()))if(ch=='-')flg=-flg;
        for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar());
        num *= flg;
    }
    const int MAXN = 85;
    const int mod = 1e9;
    int n, m, tot, id[10][10];
    int a[MAXN][MAXN], d[MAXN][MAXN], g[MAXN][MAXN];
    char s[10];
    inline void link(int u, int v) {
        ++d[u][u], ++d[v][v];
        ++g[u][v], ++g[v][u];
    }
    inline void kill(int a, int b, int &ii, int &ik, int &ki, int &kk, int &sign) {
        ii = 1, ik = 0;
        ki = 0, kk = 1;
        sign = 1;
        while(b) {
            (ii -= a/b * ki) %= mod;
            (ik -= a/b * kk) %= mod;
            a -= a/b * b;
            swap(a, b);
            swap(ii, ki);
            swap(ik, kk);
            sign = -sign;
        }
    }
    inline int Gauss(int N) {
        int ans = 1, ii, ik, ki, kk, sign;
        for(int i = 1; i <= N; ++i) {
            for(int k = i+1; k <= N; ++k) if(a[k][i]) {
                kill(a[i][i], a[k][i], ii, ik, ki, kk, sign); //先把系数算出来
                ans *= sign;
                for(int j = i; j <= N; ++j) {
                    int _aij = (1ll * a[i][j] * ii + 1ll * a[k][j] * ik) % mod;
                    int _akj = (1ll * a[i][j] * ki + 1ll * a[k][j] * kk) % mod;
                    a[i][j] = _aij, a[k][j] = _akj;
                }
            }
            ans = 1ll * ans * a[i][i] % mod;
        }
        return ans;
    }
    int main() {
        read(n), read(m);
        for(int i = 1; i <= n; ++i) {
            scanf("%s", s+1);
            for(int j = 1; j <= m; ++j)
                if(s[j] != '*') {
                    id[i][j] = ++tot;
                    if(id[i-1][j]) link(tot, id[i-1][j]);
                    if(id[i][j-1]) link(tot, id[i][j-1]);
                }
        }
        for(int i = 1; i < tot; ++i)
            for(int j = 1; j < tot; ++j)
                a[i][j] = d[i][j] - g[i][j];
        printf("%d
    ", (Gauss(tot-1) + mod) % mod);
    }
    
    
  • 相关阅读:
    【JAVASCRIPT】call和apply的用法以及区别
    web开发中的支付宝支付和微信支付
    【input】标签去除默认样式
    npm run build后如何打开index.html跑起项目
    Sass的混合-@mixin,@include
    ios h5 长按时出现黑色透明遮罩
    ios h5 长按放大镜效果关闭
    vue.$nextTick 解决了哪些问题
    原生JS代码封装(将字符串转换为日期 2019.08.24 )
    原生JS代码封装(获取年月日时分秒 )
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039322.html
Copyright © 2011-2022 走看看