当前位置:网站首页>E. XOR Tree(树形dp/异或/最近公共祖先)
E. XOR Tree(树形dp/异或/最近公共祖先)
2022-07-29 21:24:00 【罗gkv】
题意
给定一棵树,树上每个结点取值为 2 0 < = a i < 2 30 2^0<=a_i<2^{30} 20<=ai<230,如果树上存在路径path(u,v)使得,路径上的结点的异或和为0,则这条路径是损坏的。
现能够将树上任一结点的数,修改成其他的数值(可以超出 2 30 2^{30} 230)。
问,最少需要修改多少个结点,才能使树上不存在损坏的路径。
思路
- 对于损坏的路径,我们只需要把路径上的一个结点,修改成 2 31 2^{31} 231即可,因为树上结点的取值都小于 2 31 2^{31} 231,与之异或,必定非0。
- 对于损坏的路径,我们要修改离根节点最近的那个点,因为这个结点,影响面最大。修改该结点,可以最大保证破坏更多的损坏路径。
- 构建以1为根结点root的树
- 定义dis(u)为结点u与根结点组成的路径的异或和。
- 根据异或性质,对于任意结点u,v,假设它们的公共祖先为p,则路径(u,v)的异或值,实际等于 d i s ( u ) ⨁ d i s ( v ) ⨁ p dis(u)\bigoplus dis(v)\bigoplus p dis(u)⨁dis(v)⨁p
我们可以预处理,计算每个结点的dis值。dfs遍历每个结点(优先遍历子结点),对于存在损坏的路径,则破坏该路径的公共祖先结点。
在dfs遍历的时候,用set维护每个结点的所有后代结点的dis值。
注意事项
- 该题卡常,遍历数组时需要遍历小的那个,详见代码33行
- 需要清空子节点的 set集合,不然内存会爆,详见代码42行
代码
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 200010;
int n, x, y, ans;
int a[maxn], dis[maxn];
vector<int> g[maxn];
set<int> st[maxn];
// dis[u] = a[u] ^ a[parent(u)] ^ ... ^ a[root]
void cal_pre(int u, int p) {
dis[u] = a[u];
if (p != -1) {
dis[u] ^= dis[p];
}
for (auto v: g[u]) {
if(v == p) {
continue;
}
cal_pre(v, u);
}
}
void dfs(int u, int p) {
st[u].insert(dis[u]);
bool same = false;
for (auto v: g[u]) {
if (v == p) {
continue;
}
dfs(v, u);// dfs the son node first.
// if no this, TLE happen.
if (st[v].size() > st[u].size()) {
st[u].swap(st[v]);
}
for (auto x: st[v]) {
same |= st[u].count(x ^ a[u]);
}
for (auto x: st[v]) {
st[u].insert(x);
}
st[v].clear();// if no this, Memory Limit happen.
}
if (same) {
st[u].clear();
++ans;
}
}
void solve() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
g[i].clear();
st[i].clear();
}
for (int i = 1; i < n; ++i) {
scanf("%d%d", &x, &y);
g[x].push_back(y);
g[y].push_back(x);
}
cal_pre(1, -1);
ans = 0;
dfs(1, -1);
printf("%d\n", ans);
}
int main() {
int t;
// scanf("%d", &t);
t = 1;
while (t--) {
solve();
}
}
最后
weixin gongzhonghao搜 对方正在debug,关注下,一起快乐刷题吧
边栏推荐
猜你喜欢
随机推荐
SwiftUI 手势大全之可用的手势类型有哪些(教程含源码)
刚重装的win7系统不能上网(深度系统安装步骤)
leetcode-593:有效的正方形
The cornerstone of distributed: reliability - What a tangled web we weave
第二好PyTorch新手课程;论文写作指南;使用µGo语言开发迷你编译器;超高效使用Transformer的扩展库;前沿论文 | ShowMeAI资讯日报
初识网络的简单概念
sizeof和strlen的区别(strlen和sizeof的用法)
网络通信编程基础,BIO,NIO
GBASE 8s自定义存储过程和函数介绍
Xshell 7 提示 “要继续使用此程序,您必须应用最新的更新或使用新版本”
第3章业务功能开发(线索关联市场活动,插入数据并查询)
GBASE 8s 数据索引
940. Different subsequences II
【Verilog 设计】Verilog 实现偶数、奇数分频和任意小数分频
GBASE 8s 自定义存储过程和函数示例
The implementation of the flood control project and safety construction project in the flood storage and detention areas in Luluze and Ningjinbo was launched
【Verilog】Verilog设计进阶
tkinter绘制组件(31)——支点标题
GBASE 8s 数据库唯一索引
[BUG]memset和成员初始化的先后顺序








