Security Camera [ABC220H]

Posted AK DREAM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Security Camera [ABC220H]相关的知识,希望对你有一定的参考价值。

https://atcoder.jp/contests/abc220/tasks/abc220_h

题解

考虑折半搜索,将 \\(n\\) 个点分为大小为 \\(\\dfrac{n}{2}\\) 的两个集合 \\(S, T\\)

\\(F1[s]\\ (s\\subseteq S)\\) 表示如果选了 \\(s\\) 中的点安装摄像头,那么被监视的边的数量的奇偶性

\\(F2[t]\\ (t\\subseteq T)\\) 表示如果选了 \\(t\\) 中的点安装摄像头,那么被监视的两端都在 \\(T\\)的边的数量的奇偶性

\\(G[s]\\ (s\\subseteq S)\\) 表示所有 (和 \\(\\{S\\) \\ \\(s\\}\\) 中的点之间有奇数条边的) 的 \\(T\\) 中的点的集合

以上都可以在 \\(O(n*2^{\\frac{n}{2}})\\) 的时间内计算

那么一对 \\(s,t\\) 满足题目条件当且仅当:

\\[F1[s] \\oplus F2[t] \\oplus \\ (\\operatorname{popcount}(G[s]\\& T)\\&1) = 0 \\]

考虑如何计数

枚举 \\(G[s]\\& T\\),考虑计算

\\[H[P][0/1] = \\sum\\limits_{G[s]\\& T = P} [F1[s]\\oplus F2[t] = 0/1] \\]

\\[Ans=\\sum\\limits_{P\\subseteq T} H[P][\\operatorname{popcount}(P)] \\]

发现上面第一个式子长得像个集合交卷积

枚举 \\(v1=0/1, v2=0/1\\),计算 \\(C1[P]=\\sum\\limits_{G[s]=P} [F1[s]=v1], C2[P]=[F2[P]=v2]\\)

那么 \\(H[P][v1\\oplus v2] = \\sum\\limits_{s\\& t = P} C1[s]*C2[t]\\)

使用 \\(FWT\\)\\(O(n*2^{\\frac{n}{2}})\\) 的时间内计算

代码

#include <bits/stdc++.h>
#define N 50
#define M (1<<20)+5
#define pb push_back
#define lb(x) (x&-x)
using namespace std;
typedef long long ll;

int n, m, G[M], cnt[M]; 
bool F1[M], F2[M];
ll C1[M], C2[M];
vector<int> E[N];
inline int chk(int s, int x) { return (s>>x)&1; }

void FWT(ll *F, int _n, int tp) {
	for (int i = 1; i < (1<<_n); i <<= 1) {
		for (int j = 0; j < (1<<_n); j += i+i) for (int k = 0; k < i; k++) {
			F[j+k] += tp*F[i+j+k];  
		}
	}
}

int main() {
	scanf("%d %d", &n, &m);
	for (int i = 1, u, v; i <= m; i++) {
		scanf("%d %d", &u, &v); 
		E[u].pb(v); E[v].pb(u);
	}
	int t1 = n/2, t2 = n-t1;
	for (int s = 1; s < (1<<t1); s++) {
		int t = s^lb(s), x = log2(lb(s))+1;
		F1[s] = F1[t]; G[s] = G[t];
		for (auto y : E[x]) {
			if ((y<=t1&&!chk(s,y-1))||y>t1) F1[s]^=1;
			if (y > t1) G[s] ^= (1<<(y-t1-1));
		}
	}
	for (int s = 1; s < (1<<t2); s++) {
		int t = s^lb(s), x = log2(lb(s))+t1+1;
		F2[s] = F2[t]; cnt[s] = cnt[t]+1;
		for (auto y : E[x]) {
			if (y > t1 && !chk(s,y-t1-1)) F2[s]^=1;
		}
	}
	ll ans = 0; int mx = (1<<t1)-1;
	for (int v1 = 0; v1 <= 1; v1++) for (int v2 = 0; v2 <= 1; v2++) {
		memset(C1, 0, sizeof(C1)); memset(C2, 0, sizeof(C2));
		for (int s = 0; s < (1<<t1); s++) if (F1[s] == v1) ++C1[G[mx^s]];
		for (int s = 0; s < (1<<t2); s++) if (F2[s] == v2) ++C2[s];
		FWT(C1, t2, 1); FWT(C2, t2, 1);
		for (int s = 0; s < (1<<t2); s++) C1[s] = C1[s]*C2[s];
		FWT(C1, t2, -1);
		for (int s = 0; s < (1<<t2); s++) {
			if (!((cnt[s]&1)^v1^v2)) ans += C1[s];
		}
	}
	printf("%lld\\n", ans);
	return 0;
}
作者:AK_DREAM
本文版权归作者和博客园共有,欢迎转载,但必须给出原文链接,并保留此段声明,否则保留追究法律责任的权利。

Linux学习---GCC编译常见错误

  • 预处理错误:
  1. No such file or directory

出错原因:①包含错误:eg  #include <abc.h>    //abc.h为用户自行编写文件

    解决方法:⑴应改为#include “abc.h”    //用尖括号是表示从C库中寻找,一般为C自带类,如stdio.h、string.h等。应用用户自建的文件应使用“”(引号)。

         ⑵编译时添加 -I(大写i) filename(文件目录)  //将filename作为第一个寻找头文件的目录。    //参考:https://www.cnblogs.com/biglucky/p/4034923.html

 

  • 编译错误:

    语法错误:;  { }  

 

  • 链接错误:

    ① 原材料不足(函数只有声明,没有实现) undefined reference to \'fun\'

    原因:标签(函数等)只有声明,没有实现

    解决方法:寻找标签(函数)是否实现,链接时是否加入一起链接。

    ② 材料多余  multiple definition of  \'fun\'

    原因:标签(函数等)多次实现。

    解决方法:去掉多余的标签(函数)实现。

以上是关于Security Camera [ABC220H]的主要内容,如果未能解决你的问题,请参考以下文章

向以下收件人或组传递邮件失败:

内容安全策略框架-祖先

android 怎么从camera中获取流

Camera2 vs Camera1

onFaceDetection(Camera.Face[] faces, Camera camera) 继续执行

如何让视频有camera