• 主旋律[清华集训2014 Day1]


    SOL:

     这是最难的一道题。我一脸蒙蔽。

     首先我们发现正面做这道题很难。那么我们求答案的补集。

     我们把图缩点后,若其为点数大于1的DAG,那么我们就认为其不合法。

     利用容斥原理,DAG图的特征是有至少一个入度为0的点并且这个图不止一个点(这里及以下所说的点都是指求强连通后的  点),就根据这个进行容斥。

     我们枚举每一个点集。我们发现其子集对答案的贡献是负的。那么我们枚举每个集合和其子集,每个元素有三种状态,0,1,或是由1枚举子集至0,那么复杂度就是O(3^n);

    #include<bits/stdc++.h>
    #define sight(c) ('0'<=c&&c<='9')
    #define LL long long
    #define mo 1000000007
    #define L(x) ((x)&(-(x)))
    #define SIZ (1<<16)+7
    using namespace std;
    inline void read(int &x){
        static char c;
        for (c=getchar();!sight(c);c=getchar());
        for (x=0;sight(c);c=getchar()) x=x*10+c-48;
    }
    inline void add(LL &x,LL y){
        x=x+y; if (x>=mo) x%=mo; else if (x<0) (x%=mo)+=mo;
    }
    int n,m,x,y,in[SIZ],out[SIZ],cnt[SIZ];
    LL po[SIZ],num[SIZ],f[SIZ],g[SIZ],M[SIZ],siz,v,ed,sum;
    int main (){
        read(n); read(m);
        while (m--) {
            read(x),read(y);
            out[1<<x-1]|=1<<y-1; in[1<<y-1]|=1<<x-1;
        }
        po[0]=1; 
         for (int i=1;i<SIZ;i++) 
          po[i]=(po[i-1]<<1)%mo;
        siz=1<<n; 
        for (int i=1;i<siz;i++) num[i]=num[i-L(i)]+1;
        f[0]=g[0]=1; M[0]=mo-1;
        for (int i=1;i<siz;i++) {
            if (num[i]==1) {
                f[i]=M[i]=g[i]=1; continue;
            }
            x=L(i),v=i-x,ed=0;
            for (int j=0;j<n;j++) if (i&(1<<j)) ed+=num[out[1<<j]&i];
            f[i]=g[i]=po[ed],M[i]=0;
            for (int j=(v-1)&v,now=j|x;~j;j=(j-1)&v,now=j|x)  {
                add(M[i],-f[now]*M[i-now]%mo);
                if (!j) break;
            }
            cnt[i]=0; sum=M[i]*po[cnt[i]]%mo;
            for (int j=(i-1)&i;j;j=(j-1)&i) {
                int La=L(i-j),L=j|La;
                cnt[j]=cnt[L]-num[out[La]&(i-L)]+num[in[La]&j];
                add(sum,M[j]*g[i-j]%mo*po[cnt[j]]%mo);
            }
          add(f[i],-sum);add(M[i],f[i]);
        }
        printf("%lld
    ",f[(1<<n)-1]); return 0;
        return 0;
    }
  • 相关阅读:
    .NET Tools...
    函数重载
    友元课后题
    怎么防止用户输入错误信息
    C#动态求圆的面积
    重载自增
    C++数学应用
    位运算符
    MSDN放出了VS2010简体中文正式版(附下载地址)
    字符串复制
  • 原文地址:https://www.cnblogs.com/rrsb/p/8260489.html
Copyright © 2020-2023  润新知