zoukankan      html  css  js  c++  java
  • 【BZOJ4596】【SHOI2016】—黑暗前的幻想乡(矩阵树+容斥)

    传送门

    每个公司恰好一条边不好求
    容斥后变成最多n1n-1个公司有边-最多n2n-2个公司没边+最多n3n-3个公司有边……

    每次矩阵树做一次就完了

    复杂度O(2nn3)O(2^nn^3)

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ib==ob)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ib==ob)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define re register
    #define pb push_back
    inline void file(){
        #ifdef Stargazer
        freopen("lx.cpp","r",stdin);
        #endif
    }
    const int N=18;
    const int M=1<<N;
    const int mod=1e9+7;
    inline int add(int a,int b){return a+b>=mod?a+b-mod:a+b;}
    inline void Add(int &a,int b){(a+=b)>=mod?(a-=mod):0;}
    inline int dec(int a,int b){return a>=b?a-b:a-b+mod;}
    inline void Dec(int &a,int b){a=dec(a,b);}
    inline int mul(int a,int b){return 1ll*a*b>=mod?1ll*a*b%mod:a*b;}
    inline void Mul(int &a,int b){a=mul(a,b);}
    inline int ksm(int a,int b,int res=1){
        for(;b;b>>=1,a=mul(a,a))(b&1)&&(res=mul(res,a));return res;
    }
    vector<pii> e[N];
    int f[N][N],bit[M],n;
    inline void addedge(int p){
        for(pii &x:e[p]){
            Add(f[x.fi][x.fi],1),Add(f[x.se][x.se],1);
            Dec(f[x.fi][x.se],1),Dec(f[x.se][x.fi],1);
        }
    }
    inline int guass(){
        int res=1;
        for(int i=1;i<n;i++){
            int inv=ksm(f[i][i],mod-2);
            for(int j=i+1;j<n;j++){
                int t=mul(f[j][i],inv);
                for(int k=i;k<n;k++)
                    Dec(f[j][k],mul(f[i][k],t));
            }
            Mul(res,f[i][i]);
        }return res;
    }
    inline int calc(int sta){
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++){
            if(sta&(1<<(i-1)))addedge(i);
        }
        return guass();
    }
    signed main(){
        file();
        n=read();
        for(int i=1;i<M;i++)
        for(int j=0;j<N;j++)
        if(i&(1<<j))bit[i]++;
        for(int i=1;i<n;i++){
            int m=read();
            for(int j=1;j<=m;j++){
                int u=read(),v=read();
                e[i].pb(pii(u,v));
            }
        }
        int res=0;
        for(int i=0;i<(1<<(n-1));i++){
            if((n-bit[i])&1)Add(res,calc(i));
            else Dec(res,calc(i));
        }
        cout<<res;
    }
    
  • 相关阅读:
    读取json中的中文乱码
    Qt新建一个对话框
    Qt窗口全屏
    Qt设置QWidget背景图片
    Qt加载本地图片
    junit5|软断言
    Classpath resource [/data/department/createDepartment.csv] does not exist
    有个用户反馈上传头像失败,分析原因?
    手机扫描二维码的测试用例(转载)
    一次完整的HTTP请求过程是怎么样的呢?【图文详解】(转载)
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328789.html
Copyright © 2011-2022 走看看