题解我就服这个大佬QAQ http://blog.miskcoo.com/2015/05/bzoj-3812
简洁明了还赏心悦目,miskcoo家的题解超棒啊【跪在地上表白大佬
忽然很想自己搭blog【趴
良心样例啊
我怀疑是因为前几天立的flag233333 当时磕了【k个连通块】就表示,磕主旋律…………于是肝了几天,被坐在右边颓废的jq挂起来裱23333
……状压容斥的姿势我果然还是不熟练【滑稽
反正看各路题解都看的一脸懵逼,用重名变量什么的最讨厌了233333
#include<bits/stdc++.h>
#define MAXN 16
#define MAXM MAXN*MAXN
#define MOD 1000000007
using namespace std; int n,m;
inline int read(){
register char ch = getchar();
while(!isdigit(ch)) ch = getchar();
register int rtn = 0;
while(isdigit(ch)) rtn = rtn*10 + ch - '0' , ch = getchar();
return rtn;
}
int cf[MAXM];
int f[1<<MAXN] , g[1<<MAXN];
int In[1<<MAXN] , Out[1<<MAXN] , cnt[1<<MAXN];
int bitcnt[1<<MAXN] , p[1<<MAXN] , h[1<<MAXN];
int main(){
// freopen("1.in","r",stdin);
n = read() , m = read();
int mn = 1<<n;
cf[0] = 1;
for(int i=1;i<=m;++i)
cf[i] = (cf[i-1] << 1) % MOD;
for(int i=1;i<=m;++i){
int x = read()-1 , y = read()-1;
In[1<<y] |= 1<<(x);
Out[1<<x] |= 1<<(y);
}
bitcnt[0] = 0;
for(int i=1;i^mn;++i)
bitcnt[i] = bitcnt[i^(i&-i)] + 1;
for(int s = 1 ; s^mn ; ++s){
int lowbit_s = s & -s;
int out = s^ lowbit_s;
h[s] = h[out] + bitcnt[ In[lowbit_s] & out]
+ bitcnt[ Out[lowbit_s] & out];
g[s] = 0 , f[s] = cf[h[s]];
for(int R = out ; R ; (--R) &= out)
g[s] = (g[s] + MOD - 1ll* g[R] * f[s^R] % MOD) %MOD;
for(int R = s ; R ; (--R) &= s){
if(R==s) p[R] = 0;
else{
int lowbit_ = (R^s) & -(R^s);
p[R] = p[R^lowbit_]
+ bitcnt[Out[lowbit_] & R]
- bitcnt[In[lowbit_] & (R^s)];
}
f[s] = (f[s] - 1ll * cf[p[R] + h[R^s]] * g[R] % MOD + MOD) %MOD;
}
g[s] = (g[s] + f[s]) %MOD;
// printf("f[ %d ] = %d\ng[ %d ] = %d\n\n",s,f[s],s,g[s]);
}
printf("%d",(f[mn-1]%MOD+MOD)%MOD);
return 0;
}