题解:P11714 [清华集训 2014] 主旋律
MatrixGroup · · 题解
前言
高妙,学习。
题意
给定一
题解
设
强连通是不好刻画的,不过强连通缩点之后我们得到了一个 DAG。
考虑在 DAG 计数的时候我们干了什么:枚举零度点集,得到一个恒等式。我们这里也可以这样干。设
因为这个式子里
然后作为集合幂级数,
代码
cin>>n>>m;
rep(i,m)
{
cin>>u>>v;
--u;--v;
++in[1<<u|1<<v];
++qaq[1<<u][v];
}
rep(i,n) lg[1<<i]=i;
rep(i,n) rep(j,1<<n) if((j>>i)&1) in[j]+=in[j&~(1<<i)];
rep(i,n) rep(j,1<<n) qaq[j][i]=qaq[j&-j][i]+qaq[j&(j-1)][i];
pw2[0]=1;
rep1(i,1000) pw2[i]=pw2[i-1]*2%mod2;
rep(i,1<<n) g[i]=-pw2[in[i]];
g[0]=1;
rep(i,1<<n) if(i)
{
if(g[i]<0) g[i]+=mod2;
for(int j=(i+1)|i;j<(1<<n);j=(j+1)|i)
{
int k=j^i;
if(k&(k-1)) qvq[k]=qvq[k&-k]+qvq[k&(k-1)];
else qvq[k]=qaq[i][lg[k]];
g[j]=(g[j]-g[i]*pw2[in[k]+qvq[k]])%mod2;
}
}
rep(i,1<<n) if(i)
{
f[i]=-g[i];
for(int j=i&(i-1);j;j=(j-1)&i) if(j&(i&-i))
{
f[i]=(f[i]-f[j]*g[i^j])%mod2;
}
if(f[i]<0)f[i]+=mod2;
}
cout<<f[(1<<n)-1]<<'\n';