ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[CF1670E]Hemose on the Tree 题解

2022-07-11 13:35:48  阅读:130  来源: 互联网

标签:小于 int 题解 CF1670E Tree tot 异或 权值 define


传送门QAQ

Preface

还是不会构造题啊>_<

发现性质的能力还是弱了点。

Analysis

直接说这题的结论:异或和的最小最大值为 \(n\)。

很简单,只要存在一个点和它连出去的边,两个的权值一个 \(\ge n\),一个 \(\lt n\),由于 \(n = 2^p\),珂以推出两者的异或和 \(\ge n\)。

而这样的一个点显然存在,不然所有点和边的权值没法构成一个 \(1\sim 2n-1\) 的排列。

题目中两个样例的异或和最小最大值均为 \(n\),那么我们可以考虑构造一个图使其满足这点。

首先思考异或和 \(\le n\) 的条件,对于相连的点和边,它们的权值肯定满足以下两者之一:

  • 两个权值都小于 \(n\) 或不小于 \(n\)。

  • 一个权值不小于 \(n\),一个权值小于 \(n\)。

因为要构造 \(1\sim 2n-1\) 的排列,如果都小于 \(n\) 后续会比较难处理,而且第二个条件看着就比较像构造题常用的套路,循环往复,一个不小于 \(n\),一个小于 \(n\),接下来的一个又不小于 \(n\),如此往后推导。

所以考虑让所有点边满足第二个条件。

下面就需要一些经验和大胆的猜测与尝试了。

如果我们直接把根节点权值设为 \(n\) 会怎样?

显然接下来的边权就要大于 \(n\) 了,设为 \(n+k(1 \le k\lt n)\),那么下面连着的点权我们可以将其设为 \(k\)。

推一推可以发现,有一种构造方法能满足题目要求:

  • 当前点异或和为 \(n\) 时,下面的边权设为 \(n+k\),连着的点为 \(k\)。

  • 当前点异或和为 \(0\) 时,下面的边权设为 \(k\),连着的点为 \(n + k\)。

(注意,上述 \(k\) 是动态更新的,即每次递归到下一层 \(k\gets k+1\))。

只要这样构造,异或和只有三种情况:\(0,k,n\),

这样就满足了最小最大值为 \(n\),而且根节点没有限制,直接指定 \(1\) 为根节点就好啦~

时间复杂度 \(O(N)\)。

Code

#include <bits/stdc++.h>
#define pb emplace_back
#define fir first
#define sec second
#define mp make_pair 
using namespace std;
const int maxn = 1e6 + 5;
int p,n;
vector<pair<int,int> > g[maxn];
int ans1[maxn],ans2[maxn],tot;
void dfs(int u,int flag,int fa) {
	for(auto p : g[u]) {
		int v = p.fir,w = p.sec;
		if(v == fa)continue ;
		++ tot;
		ans2[w] = flag ^ tot;
		ans1[v] = flag ^ tot ^ n;
		dfs(v , flag ^ n , u);
	}
	return ;
} 
void work() {
	scanf("%d",&p);
	n = 1 << p;
	tot = 0;
	for(int i = 1;i <= n;++ i)g[i].clear();
	for(int i = 1;i < n;++ i) {
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].pb(mp(v , i));
		g[v].pb(mp(u , i));
	}
	ans1[1] = n;
	dfs(1 , n , 0);
	puts("1");
	for(int i = 1;i <= n;++ i)printf("%d ",ans1[i]);
	puts("");
	for(int i = 1;i < n;++ i)printf("%d ",ans2[i]);
	puts("");
	return ;
}
int main() {
	int T;
	scanf("%d",&T);
	while(T --)work();
	return 0;
}

完结撒花✿✿ヽ(°▽°)ノ✿

标签:小于,int,题解,CF1670E,Tree,tot,异或,权值,define
来源: https://www.cnblogs.com/663B/p/16466053.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有