首页 > 其他分享 >CF908H New Year and Boolean Bridges

CF908H New Year and Boolean Bridges

时间:2023-11-01 17:11:40浏览次数:32  
标签:联通 limits sum Boolean FWT New CF908H mathtt operatorname

这说明你那破子集卷积不是万能的。

显然题目要求的图 \(G'\) 是弱联通的,考虑给出的图 \(G\) 中两个点 \(i,j\) 之间 \(G_{i,j}\) 的条件转化为:

  • \(G_{i,j}=\mathtt A\),说明 \(i\) 能到 \(j\) 且 \(j\) 能到 \(i\),则 \(i,j\) 在 \(G'\) 的同一个强连通分量中。
  • \(G_{i,j}=\mathtt O\),说明 \(i\) 能到 \(j\) 或者 \(j\) 能到 \(i\),由于 \(G_{i,j}=\mathtt A/\mathtt X\) 是严格强于这个限制的,所以可以转换为 \(G'\) 中任意两点 \(u,v\) 之间至少存在一条路径从 \(u\) 到 \(v\) 或从 \(v\) 到 \(u\)。
  • \(G_{i,j}=\mathtt X\),说明只能从 \(i\) 到 \(j\) 或从 \(j\) 到 \(i\),这要求 \(i,j\) 不在 \(G'\) 的同一个强连通分量中。

考虑仅由 \(\mathtt A\) 边构成的极大导出子图 \(G_\mathtt A\subseteq G\),显然图 \(G_\mathtt A\) 中同一个弱连通块内的任意两点 \(u,v\) 在图 \(G'\) 中强连通,于是如果 \(G_{u,v}=\mathtt X\) 就矛盾了,先判掉这种情况,答案为 \(-1\)。

否则的话必然有解,存在一种构造:考虑 \(G_{\mathtt A}\) 中的某个大小 \(\ge 2\) 的弱联通块,将内部的点拿出来,在 \(G'\) 中单独组成一个环;然后 \(G'\) 中就变成了若干个环加上若干孤立点,把它们串成一条链即可满足所有 \(\mathtt O\) 边的性质。
于是每个环(\(G_{\mathtt A}\) 中的弱连通块) \(C\) 内部有 \(|V_C|\) 条边,然后会连出去一条边;每个孤立点连出去一条边;最后有一个部分不用连出去边。设环集合为 \(\operatorname{cyc}\),那么总边数就是 \(\sum\limits_{C\in \operatorname {cyc}}(|V_C|+1)+(n-\sum|V_C|)-1=n-1+|\operatorname{cyc}|\)。

但是我们发现图 \(G_{\mathtt A}\) 中的两个大小 \(\ge 2\) 的弱联通块是可以合并的,因为两个弱联通块内的点在 \(G'\) 中可以属于同一个强连通分量,那么 \(|\operatorname{cyc}|\) 就会减少 \(1\),边数就会变少。所以我们希望能够合并尽可能多的弱连通块,使得最后弱联通块总数最少。注意到 \(G_{u,v}=\mathtt X\) 的限制相当于 \(u\) 所在的弱联通块不能和 \(v\) 所在的弱连通块合并。

由于我们考虑的弱联通块大小 \(\ge 2\),所以弱联通块数 \(m\le\frac{n}{2}\le 23\)。考虑状压 dp,\(f_{i,S}\) 表示能否将弱联通块集合 \(S\) 全部合并成 \(i\) 个块。那么 \(\text{ans}=n-1+\min\limits_{f_{i,U}=1}i\),\(U\) 为弱联通块全集。

首先 \(f_{1,S}\) 是易求的,预处理 \(w_i\) 表示第 \(i\) 个弱联通块不能合并的弱联通块集合即可。然后考虑判定性问题转计数问题,\(f_{i,S}\) 表示合并方案数,对于 \(i\ge 2\):

\[f_{i,S}=\sum\limits_{S_1\cup S_2=S,S_1\cap S_2=\varnothing}f_{i-1,S_1}f_{1,S_2} \]

不难发现这就是个子集卷积,但是复杂度 \(O(m^32^m)\),拿头跑都过不了。但是由于我们不关心 \(f_{i,S}\) 的具体值,对同一个方案可以算重,而且若 \(f_{i,S}\neq 0\) 必然有 \(f_{i,T}\neq 0,T\subseteq S\)。所以我们就可以直接把 \(S_1\cap S_2=\varnothing\) 的限制去掉了。最后相当于一个或卷积,复杂度 \(O(m^22^m)\),好像已经可以过了,但是能做到更优。

考虑到进行 FWT 或变换(高维前缀和)后 \([x^S]\operatorname{FWT}(F_{i-1})\) 到 \([x^S]\operatorname{FWT}(F_{i})\) 的转移系数固定为 \([x^S]\operatorname{FWT}(F_1)\),于是我们可以预先求出 \(f_{1}\) 的集合幂级数 \(F_1\) 后进行 FWT,于是 \([x^S]\text{FWT}(F_{i})=([x^S]\operatorname{FWT}(F_1))^i\)。

最后的问题就是如何求出 \([x^U]F_i\)。根据高维前缀和的性质有:

\[[x^S]\operatorname{FWT}(F_i)=\sum\limits_{T\subseteq S}[x^T]F_i \]

子集反演得:

\[[x^S]F_i=\sum\limits_{T\subseteq S}(-1)^{|S|-|T|}[x^T]\operatorname{FWT}(F_i) \]

所以:

\[\begin{aligned}[x^U]F_i&=\sum\limits_{T}(-1)^{m-|T|}[x^T]\operatorname{FWT}(F_i)\\&=\sum\limits_{T}(-1)^{m-|T|}([x^T]\operatorname{FWT}(F_1))^i\end{aligned} \]

可以 \(O(2^m)\) 求出,而 \(i\) 的上界为 \(m\),所以复杂度就是 \(O(m2^m)\)。

// Problem: New Year and Boolean Bridges
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/CF908H
// Memory Limit: 500 MB
// Time Limit: 5000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define mt make_tuple
#define mp make_pair
#define fi first
#define se second

using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef tuple<int, int, int> tu;
bool Mbe;

const int N = 50;
const int T = (1 << 23) + 100;

int n, m, S, fa[N], sz[N], w[N], id[N];
ll op[T], f[T], c[T];
char s[N][N];

int gf(int x) { return x == fa[x] ? x : fa[x] = gf(fa[x]); }
void mrg(int x, int y) {
	if ((x = gf(x)) == (y = gf(y))) return;
	fa[x] = y, sz[y] += sz[x];
}

void FWT(ll *f) {
	for (int o = 2, k = 1; o <= S; o <<= 1, k <<= 1)
		for (int i = 0; i < S; i += o)
			for (int j = 0; j < k; j++)
				f[i + j + k] += f[i + j];
}

void solve() {
	cin >> n;
	for (int i = 1; i <= n; i++) sz[fa[i] = i] = 1;
	for (int i = 1; i <= n; i++) {
		cin >> (s[i] + 1);
		for (int j = 1; j < i; j++) 
			if (s[i][j] == 'A') mrg(i, j);
	}
	for (int i = 1; i <= n; i++) {
		if (gf(i) == i && sz[i] >= 2) id[i] = ++m;
		id[i] = id[gf(i)];
	}
	if (!m) return cout << n - 1 << '\n', void();
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j < i; j++) {
			if (s[i][j] == 'X') {
				if (id[i] && id[i] == id[j]) return cout << -1 << '\n', void();
				else if (id[i] && id[j]) w[id[i]] |= (1 << id[j] - 1), w[id[j]] |= (1 << id[i] - 1);
			}
		}
	}
	S = (1 << m), op[0] = 1;
	for (int i = 1; i < S; i++) {
		int j = __lg(i & -i);
		op[i] = op[i ^ (1 << j)] & (!(w[j + 1] & (i ^ (1 << j))));
	} 
	if (op[S - 1]) return cout << n << '\n', void();
	FWT(op), memcpy(f, op, sizeof(ll) * (S + 5));
	for (int i = 0; i < S; i++) c[i] = (m - __builtin_popcount(i) & 1) ? -1 : 1;
	for (int r = 2; ; r++) {
		ll res = 0;
		for (int i = 0; i < S; i++) f[i] *= op[i], res += f[i] * c[i];
		if (res) return cout << n - 1 + r << '\n', void();
	}
}

bool Med;
int main() {
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cerr << (&Mbe - &Med) / 1048576.0 << " MB\n";
	#ifdef FILE
		freopen("1.in", "r", stdin);
		freopen("1.out", "w", stdout);
	#endif
	int T = 1;
	// cin >> T;
	while (T--) solve();
	cerr << (int)(1e3 * clock() / CLOCKS_PER_SEC) << " ms\n";
	return 0;
}

标签:联通,limits,sum,Boolean,FWT,New,CF908H,mathtt,operatorname
From: https://www.cnblogs.com/Ender32k/p/17803577.html

相关文章

  • 'ProxyError('Cannot connect to proxy.', NewConnectionError
      MicrosoftVisualC++Redistributableisnotinstalled,thismayleadtotheDLLloadfailure.                Itcanbedownloadedathttps://aka.ms/vs/16/release/vc_redist.x64.exeTraceback(mostrecentcalllast): File"E:/other/lightvit......
  • NewStarCTF 2023 公开赛道 WEEK4|MISC 部分WP
    R通大残1、题目信息R通大残,打了99,补!2、解题方法仔细分析题目,联想到隐写的R通道。首先解释一下:R是储存红色的通道,通道里常见有R(红)、G(绿)、B(蓝)三个通道,如果关闭了R通道图片就没有红色的部分,G、B同理。因此我们想到R大残应该是不显示红色了,猜测结果就在R通道里,所以使用Stegsolv......
  • 无涯教程-Clojure - Adding a New Key to the Structure函数
    由于结构是不可变的,因此可以将另一个键添加到结构中的唯一方法是创建新结构。示例(nsclojure.examples.example(:gen-class))(defnExample[](defstructEmployee:EmployeeName:Employeeid)(defemp(struct-mapEmployee:EmployeeName"Learnfk":Employeei......
  • fetchMetadata: sill resolveWithNewModule [email protected] checking installable s
    在使用vue-element-admin,npm安装时一直卡在这里报错换源,跟换安装方式都不能解决。最后找到问题,这个是由于安装tui-editor时报错,解决的办法是删掉package.json的tui-editor配置项,之后再次安装大家可以查下tui-editor是干什么用的,不需要就直接删了,然后安装 ......
  • PCB封装命名规则,本文转载https://www.xjx100.cn/news/432127.html?action=onClick
    SO、SOP、SOIC、MSOP、TSSOP、TSOP、VSSOP、SSOP、SOJ封装详解 1. 简要信息如下: 2.SOP和SOIC的规格多是类似的,现在大多数厂商基本都采用的是SOIC的描述:SOIC8有窄体150mil的(外形封装宽度,不含管脚,下同),管脚间距是1.27mm,如下:有宽体的208mil的,管脚间距是1.27mm,如下:......
  • 【论文阅读笔记】【OCR-文本识别】 From Two to One: A New Scene Text Recognizer wi
    VisionLANICCV2021读论文思考的问题论文试图解决什么问题?使用语言模型对识别的文本的上下文语义信息进行建模时,会有以下问题:引入额外的计算量;识别的视觉和语言特征很难做一个很好的融合、互补能否在不使用语言模型的情况下,直接赋予视觉模型一定的语言建模能力?......
  • cdp Page.addScriptToEvaluateOnNewDocument
     加载新页面之前插入自定义的JavaScript脚本  selenium过环境检测```pythonwithopen(path+'/stealth.min.js')asf:js=f.read()driver.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument",{"source":js})``` ......
  • NewStarCTF 2023 公开赛道 Week3
    官方WPhttps://shimo.im/docs/QPMRxzGktzsZnzhz/readNewStarCTF2023Week3官方WriteUp.htmlCryptoRabin'sRSA参考博客:RSA攻击之Rabin密码体制_rsarabin-CSDN博客使用轩禹一把梭了Misc阳光开朗大男孩社会主义核心价值观https://ctf.bugku.com/tool/cvecode解码得......
  • 一键解决[notice] A new release of pip available: 22.2 -> 22.2.2 [notice] To updat
    [notice]Anewreleaseofpipavailable:22.2->22.2.2[notice]Toupdate,run:python.exe-mpipinstall--upgradepip文章目录问题描述解决思路解决方法问题描述[notice]Anewreleaseofpipavailable:22.2->22.2.2[notice]Toupdate,run:python.exe-mpip......
  • 嵌入式刷题(day2 new delete 和malloc free的区别)
    (文章目录)前言本篇文章我们来讲解一下newdelete和mallocfree的区别,这个区别在许多面试题中也会经常问到,那么我们就具体的来看看他们有什么不同吧。一、区别new和delete是C++中的运算符,用于动态分配和释放内存空间,而malloc和free是C语言中的函数,用于同样的目的......