首页 > 其他分享 >[AGC050F] NAND Tree

[AGC050F] NAND Tree

时间:2023-06-05 17:22:56浏览次数:40  
标签:ch int Tree NAND --- AGC050F operatorname getchar

求一个计数方案奇偶性的题考虑套路的交换两个元素。考虑最开始选的两条边,如果它们没有交,那么互换顺序之后结果不变。我们只需要统计相交的情况即可。

再考虑边相邻的情况。对于y---x---z,按两种顺序缩边的结果分别为 \(\operatorname{NAND}(\operatorname{NAND}(y,x),z)\) 和 \(\operatorname{NAND}(y,\operatorname{NAND}(x,z))\)。注意到 \(y=z\) 时两者等价。而 \(y\neq z\) 时,我们会得到不同的结果。

于是有了关键性质:我们将规则修改为每次选择一个点,如下图缩边:

  \       |      /                       \ | /
--- x --- y --- z ---        =>        --- x ---
  /       |      \                       / | \

答案不会变化。

先考虑共有偶数条边的情况。我们称一个节点是好的当且仅当它的权值为 1 且有奇数种方案使得它最后被保留下来。答案即为好点的数量。

考虑检查一个节点 \(x\) 是否是好的。我们先将 \(x\) 设为根,并假设每次操作都涉及根(不然两个方向等价)。

共有奇数条边的情况,枚举第一次操作转化为偶数条边即可。

按官方题解的说法这个东西相当于拓扑序计数(?),直接写一个就WA了。实际上考虑将树选完肯定会是一组完美匹配,我们这里把一组匹配到的点缩到一起,答案相当于这棵新树的拓扑序计数。

#include <bits/stdc++.h>

using namespace std;

#define ctz(x) (!(x)?0:__builtin_ctz((x)))

const int N = 505;

inline int read() {
	register int s = 0, f = 1; register char ch = getchar();
	while (!isdigit(ch)) f = (ch == '-' ? -1 : 1), ch = getchar();
	while (isdigit(ch)) s = (s * 10) + (ch & 15), ch = getchar();
	return s * f;
}

set<int> e[N], t[N];

int id[N], val[N], a[N], n;

inline void shrink(int u, int v) {
	if (u > v) swap(u, v);
	for (int i = 1; i < v; ++i) id[i] = i; id[v] = u;
	for (int i = v + 1; i <= n; ++i) id[i] = i - 1;
	for (int i = 1; i <= n; ++i) val[id[i]] = a[i], t[i].clear();
	val[id[u]] = !(a[u] & a[v]);
	for (int i = 1; i <= n; ++i) {
		for (int j : e[i])
			if (id[i] != id[j])
				t[id[i]].insert(id[j]);
	}
}

int siz[N];
bool par[N];

inline int dfs(int now, int fa) {
	siz[now] = 1;
	for (int i : t[now])
		if (i != fa) {
			int v = dfs(i, now);
			if (v == -1) return -1;
			if (v) {
				if (!par[now]) par[now] = 1;
				else return -1;
			}
			siz[now] += siz[i];
		}
	return par[now] ^ 1;
}

inline int calc(int n) {
	int res = 0, fn = 0;
	for (int i = 1; i <= n / 2; ++i) fn += ctz(i);
	for (int i = 1; i <= n; ++i) {
		if (!val[i]) continue;
		for (int j = 1; j <= n; ++j) par[j] = 0;
		if (dfs(i, 0) == -1) continue;
		int cnt = fn;
		for (int j = 1; j <= n; ++j)
			if (par[j]) cnt -= ctz(siz[j] / 2);//, cerr << "C : " << ctz(siz[j] / 2) << endl;;
		res ^= (cnt == 0);
//		cerr << fn << ' ' << cnt << ' ' << res << endl;
	} return res;
}

int main() {
	n = read();
	for (int i = 1, u, v; i < n; ++i) {
		u = read(); v = read();
		e[u].insert(v);
		e[v].insert(u);
	}
	for (int i = 1; i <= n; ++i) a[i] = read();
	if (n & 1) {
		for (int i = 1; i <= n; ++i)
			t[i] = e[i], val[i] = a[i];
		printf("%d\n", calc(n));
	} else {
		int res = 0;
		for (int i = 1; i <= n; ++i)
			for (int j : e[i])
				if (i < j) {
					shrink(i, j);
					res ^= calc(n - 1);
				}
		printf("%d\n", res);
	}
	return 0;
}

标签:ch,int,Tree,NAND,---,AGC050F,operatorname,getchar
From: https://www.cnblogs.com/wwlwakioi/p/17458463.html

相关文章

  • DRTREE - Dynamically-Rooted Tree 题解
    DRTREE-Dynamically-RootedTree本题建议评蓝。思路:题目就是要对一颗不定根树求子树权值和。这题不带修,如果带修难度会增加一点,就跟遥远的国度差不多。首先分析一下在以不同根下子树的变化。当一颗树以1号节点为根时,比如说长这样:假设每个点的权值为1,那么这8个点......
  • 【Windows】TreeSoft数据库管理系统 TreeDMS 和 TreeNMS
    官方地址:http://www.treesoft.cn/dms.html#learningTreeSoft数据库管理系统TreeDMS支持MySQL,MariaDB,Oracle,PostgreSQL,SQLServer,DB2,MongoDB,Hive,SAPHANA,Sybase,Caché,Informix,Impala,ElasticSearch,clickHouse,cassandra,AmazonRedshift,达梦DM,金仓Kin......
  • Map系列集合:TreeMap集合的原理、使用
        ......
  • Set系列集合:TreeSet集合
                 ......
  • 如何在tree中添加一个 contextmenu 事件!
    关键点就是TreeList上下文中要有这个被包装了的handleContextMenu定义TreeList时,继承了一些东西,还可以重写一些东西。 本例中,TreeList上下文捕获到右键菜单事件后,将该事件传递给了自定义的函数itemcontextmenu1对应的函数应该returnfalse来阻止默认菜单的行为。在函......
  • 如何在tree中添加一个 contextmenu 事件?
     /***添加绑定事件*<pre><code>*//绑定单个事件*list.on('itemclick',function(ev){*alert('21');*});*//绑定多个事件*list.on('itemrendereditemupdated',function(......
  • Vue通用下拉树组件@riophae/vue-treeselect的使用
    vue-treeselect是一款下拉树通用组件。@riophae/vue-treeselect是一个基于Vue.js的树形选择器组件,可以用于选择树形结构的数据。它支持多选、搜索、异步加载等功能,可以自定义选项的样式和模板。该组件易于使用和扩展,适用于各种类型的项目。npm:https://www.npmjs.com/package/@......
  • [CF9D]How many trees?
    2023-06-01题目题目传送门难度&重要性(1~10):5题目来源Codeforces,luogu题目算法dp解题思路深度最大为\(n\left(1\len\le35\right)\)的二叉树暴力枚举显然不行,考虑dp。设\(f_{i,j}\)表示有\(i\)个节点时,深度不大于\(j\)的二叉树数量。答案容斥:\(f_{n,n}-f_{n......
  • tree_diameter
        publicstaticintheight(BinTreeT){if(T==null){return-1;}else{returnMath.max(height(T.left),height(T.right))+1;}}/**ReturnthediameterofT.*/publicstaticintdiameter(BinTreeT){if(T==null){return0;}else{in......
  • 如何使用TreeView展示树状数据
    如何使用TreeView展示树状数据TreeView是一个可用于显示树形数据结构的UI组件。它提供了一个可折叠、可展开的树状视图。TreeView是一个树状结构,其根节点的类型是TreeItem。每个TreeItem又可以包含若干TreeItem。由此可组成一颗树形结构。效果展示示例代码importj......