首页 > 其他分享 >UOJ #37. 【清华集训2014】主旋律 整理--zhengjun

UOJ #37. 【清华集训2014】主旋律 整理--zhengjun

时间:2023-07-22 12:00:11浏览次数:34  
标签:cnt limits -- sum 37 zhengjun varnothing subseteq

好像没做过 DAG 计数的题。

首先看到数据范围,考虑状压。

方便起见,记 \(cnt_{S,T}=\sum\limits_{(u,v)\in E}[u\in S \and v \in T]\)。

设 \(f_S\) 表示 \(S\) 为强连通分量的选边方案数,由于正面很难算。

考虑反面:

\[f_S=2^{cnt_{S,S}}-\sum\limits_{\varnothing\subsetneqq T \subseteq S}g_T\times 2^{cnt_{S\backslash T,S}}\\ g_S=\sum\limits_{\varnothing \subsetneqq T \subseteq S}g_{S\backslash T}\times (-f_T) \]

初始:

\[f_{\varnothing}=0,g_{\varnothing}=-1 \]

这里使用了一个容斥,意思是枚举 \(S\) 的子集 \(T\) 作为出度为 \(0\) 的若干强连通分量的并集。

那么剩下的 \(S\backslash T\) 连出去的边就可以任意选或不选。

但是这样会算重,因为考虑一种选边方案使得出度为 \(0\) 的强连通分量为 \(T_1,T_2,\cdots,T_k\)。

那么这种方案会在任意 \(\varnothing \subsetneqq P\subseteq\{1,2,\cdots k\}\) 的时候被 \(T=\bigcup\limits_{i\in P}T_i\) 计算一次。

由于 \(1=\sum\limits_{\varnothing \subsetneqq P\subseteq\{1,2,\cdots k\}}(-1)^{|P|-1}\),所以加上这个容斥系数就能做到恰好算到一次。

于是 \(g_{\varnothing}=-1\),转移时 \(g\) 乘上 \(f\) 时会多乘一个 \(-1\)。

注意转移顺序,应该先转移 \(g\),再转移 \(f\),然后等 \(f_S\) 计算好了,再加到 \(g_S\) 上去。

因为计算 \(f_S\) 时所需的 \(g_S\) 是至少两个小集合并起来的,不能算上自己。

另外 \(cnt_{S,S}\) 可以预处理,\(cnt_{S\backslash T,S}\) 可以在每个 \(S\) 的时候枚举 \(T\) 计算一次。

时间复杂度:\(O(3^n\log \log)\),瓶颈在于计算 popcount。

代码

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
const int N=15,M=1<<N,E=N*N,mod=1e9+7;
int n,m,U,a[N][N];
int to[N],cnt[M],f[M],g[M],h[M],pw[E];
int main(){
	freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	cin>>n>>m,U=(1<<n)-1;
	for(int i=pw[0]=1;i<=m;i++)pw[i]=pw[i-1]*2%mod;
	for(int u,v;m--;){
		cin>>u>>v,a[--u][--v]=1;
	}
	for(int u=0;u<n;u++){
		for(int v=0;v<n;v++)to[u]|=a[u][v]<<v;
	}
	for(int S=0;S<=U;S++){
		int i=__builtin_ctz(S);
		cnt[S]=cnt[S^(S&-S)];
		for(int j=0;j<n;j++)if(S>>j&1)cnt[S]+=a[i][j]+a[j][i];
	}
	g[0]=mod-1;
	for(int S=1;S<=U;S++){
		for(int T=S;T;--T&=S)if(T&(S&-S)){
			g[S]=(g[S]+1ll*g[S^T]*(mod-f[T]))%mod;
		}
		h[S]=0;
		for(int T=S;T;--T&=S){
			if(T<S){
				int i=__builtin_ctz(S^T);
				h[T]=h[T^(1<<i)]+__builtin_popcount(to[i]&S);
			}
			f[S]=(f[S]+1ll*g[T]*pw[h[T]])%mod;
		}
		f[S]=(pw[cnt[S]]-f[S]+mod)%mod;
		g[S]=(g[S]+f[S])%mod;
	}
	cout<<f[U];
	return 0;
}

标签:cnt,limits,--,sum,37,zhengjun,varnothing,subseteq
From: https://www.cnblogs.com/A-zjzj/p/17573115.html

相关文章

  • 线段树
    //单点修改查询//http://ybt.ssoier.cn:8088/problem_show.php?pid=1549//https://www.luogu.com.cn/problem/P1198//用一维数组来存,当作完全二叉树来存#include<bits/stdc++.h>usingnamespacestd;constintN=2e5+10;longlongintm,p,n,last,t;charop;structnod......
  • 虚拟机安装clion
    虚拟机安装clion软件在jetbrains官网下载,进入网址https://www.jetbrains.com/clion/download/#section=linux,选择linux版本,点击download进行下载。在window上面下载好了后,运行虚拟机vmwareworkstation,我虚拟机是16.1,虚拟机镜像文件是ubuntu18.04软件通过filezilla进行传输,也......
  • 动态规划5.1-概述
    一、概念以下内容摘自代码源两个要求最优子结构:大问题的解可以从小问题的解推出,在问题的拆解过程中不能无限递归无后效性:未来与过去无关,一旦得到小问题的解,得到该解的过程不影响大问题的求解两个元素状态:求解过程进行到了哪一步,可以理解为一个子问题转移:从一个状态(......
  • 机器学习编译(一):概述
    机器学习编译是一个process,把机器学习的开发转到部署。机器学习编译的目标IntegrationandDependencyMinimization.集成与最小化依赖.部署应用需要集成必要的元素,我们希望部署应用的时候尽可能减小应用的大小。LeverageHardwareNativeAcceleration.利用硬件原......
  • 整理salt的grain模块
    #查找salt-minion之grains首先配置为默认的:查看配置文件:/et/salt/minion文件中,参数default_include,默认为minion.d/*.conf/etc/salt/minion.d/1.confgrains:wusen:name:无敌战神sudosystemctlrestartsalt-minionsalt-callgrains.itemwusen这样就是在grain......
  • git push origin HEAD:refs/for/master 的意思(转)
    原文:https://blog.csdn.net/u010312474/article/details/1079156941.gitpush<远程主机名><本地分支名>:<远程分支名>例如gitpushoriginmaster:refs/for/master是将本地的master分支推送到远程主机origin上的对应master分支origin是远程主机名,第一个master是本地分支名,第......
  • Mybatis练习CRUD
    namespacenamespcae中的包名要和mapper接口中的方法名一致-id:就是对应的namespace中的方法名-resultType:Sql语法执行的返回值-parameter:  参数类型1、select(选择、查询语句)1、编写接口List<User>getUserList();2、编写mapper中sql语句<selectid="getUserLi......
  • try-except-else-finally
    1'''21.语法:3try:4#可能引发异常的代码5exceptExceptionType1:6#处理异常类型1的代码7exceptExceptionType2:8#处理异常类型2的代码9else:10#如果没有发生异常,执行此处的代码11final......
  • 2023巅峰极客 Crypto Rosita
    解题思路根据以上方法求出模数pdeffind_gcd(numbers):#求c中各元素的最大公约数result=numbers[0]fornuminnumbers[1:]:result=gcd(result,num)returnresultx=[(471351354539958688729428118750100914168908093467492698485305204663714......
  • TextBox定位到指定文字处
    新建时是WPF应用程序的程序,框架.NET6xaml中<TextBoxx:Name="txt"TextWrapping="Wrap"VerticalScrollBarVisibility="Auto"AcceptsReturn="True"></TextBox>AcceptsReturn="True"输入enter时可以换行,之前是不换行的cs中in......