我是靠谱客的博主 隐形芝麻,最近开发中收集的这篇文章主要介绍LOJ2351「JOI 2018 Final」毒蛇越狱 容斥+子集卷积,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题面

题目传送门

解法

  • 暴力显然是枚举 ? ? ?到底填什么,那么单次询问的复杂度为 O ( 2 c n t ? ) O(2^{cnt_?}) O(2cnt?),并没有什么可以优化的地方。
  • 不妨考虑一个容斥,将 ? ? ?全部看作是 1 1 1,然后求子集的权值和。但是我们会将某些位置强制为 1 1 1却填成 0 0 0的数算入答案,那么我们还要减去这部分的答案。容斥的复杂度为 O ( 2 c n t 1 ) O(2^{cnt_1}) O(2cnt1)
  • 可以发现,因为 n n n只到 20 20 20,所以 min ⁡ ( c n t 0 , c n t 1 , c n t ? ) min(cnt_0,cnt_1,cnt_?) min(cnt0,cnt1,cnt?)至多只有 6 6 6。那么我们只要看哪一个最小然后相应地容斥或者暴力枚举即可。
  • 时间复杂度: O ( n × 2 n + 2 ⌊ n 3 ⌋ × q ) O(ntimes2^n+2^{lfloorfrac{n}{3}rfloor}times q) O(n×2n+23n×q)

代码

#include <bits/stdc++.h>
#define ll long long
using namespace std;
template <typename T> void read(T &x) {
	x = 0; int f = 1; char c = getchar();
	while (!isdigit(c)) {if (c == '-') f = -1; c = getchar();}
	while (isdigit(c)) x = x * 10 + c - '0', c = getchar(); x *= f;
}
const int N = 1 << 20;
int cnt[N], val[N], s[N][2];
int main() {
	int n, q; read(n), read(q); int m = (1 << n) - 1, t = n / 3;
	for (int i = 1; i <= m; i++) cnt[i] = cnt[i - (i & -i)] + 1;
	for (int i = 0; i <= m; i++) {
		char c = getchar();
		while (!isdigit(c)) c = getchar();
		s[i][0] = s[i][1] = val[i] = c - '0';
	}
	for (int j = 0; j < n; j++)
		for (int i = 0; i <= m; i++)
			if ((i >> j) & 1) s[i][0] += s[i ^ (1 << j)][0], s[i ^ (1 << j)][1] += s[i][1];
	while (q--) {
		int s0 = 0, s1 = 0, s2 = 0, ans = 0;
		char st[30]; scanf(" %s", st);
		for (int i = 0, j = n - 1; i < n; i++, j--)
			if (st[i] == '0') s0 |= (1 << j);
				else if (st[i] == '1') s1 |= (1 << j);
					else s2 |= (1 << j);
		if (cnt[s0] <= t) {
			for (int ts = s0; ; ts = s0 & (ts - 1)) {
				(cnt[ts] & 1) ? ans -= s[s1 | ts][1] : ans += s[s1 | ts][1];
				if (!ts) break;
			}
		} else if (cnt[s1] <= t)
			for (int ts = s1; ; ts = s1 & (ts - 1)) {
				(cnt[ts ^ s1] & 1) ? ans -= s[s2 | ts][0] : ans += s[s2 | ts][0];
				if (!ts) break;
			}
		else
			for (int ts = s2; ; ts = s2 & (ts - 1)) {
				ans += val[s1 | ts];
				if (!ts) break;
			}
		cout << ans << 'n';
	}
	return 0;
}

最后

以上就是隐形芝麻为你收集整理的LOJ2351「JOI 2018 Final」毒蛇越狱 容斥+子集卷积的全部内容,希望文章能够帮你解决LOJ2351「JOI 2018 Final」毒蛇越狱 容斥+子集卷积所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(32)

评论列表共有 0 条评论

立即
投稿
返回
顶部