Educational Codeforces Round 132 (Rated for Div. 2) E. XOR Tree(启发式合并+贪心)

文章讲述了如何在n个点的树中,通过修改最少的点的权值,使得树上不存在异或和为0的简单路径。关键思路是利用LCA节点进行检查,通过DFS和启发式合并的方法实现,避免了使用公共map导致的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目

n(n<=2e5)个点的树,点i权值ai(1<=ai<2^30)

修改最少的点的权值,使得树上不存在异或和为0的简单路径,输出最少的点数

权值可以被修改成任意正整数(可以是无限大)

思路来源

官方题解 & zlt题解

题解

假设树形是固定的,dfs往上回溯的时候,

如果一条路径xor为0,这条路径上必须改一个值,

贪心地来看,lca必须要改

由于可以改成任意值,改lca视为把这棵子树断掉

XOR(u,v) = XOR(根到u) xor XOR(根到v) xor a[lca(u,v)]

那就是判一下某个点的子树是否存在两个点的祖先异或,等于本身的权值

这个可以启发式合并的时候,把小的集合往大的集合上挂的时候判断

删除某个点,就可以认为是清空集合

心得

自己的写法怎么写都写不对,都wa8,感觉是启发式合并公有map导致的

只能抄官方题解,每个节点维护一个set了

代码

#include<iostream>
#include<cstdio>
#include<unordered_map>
#include<set>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,ll> P;
#define fi first
#define se second
#define pb push_back
const int N=2e5+10,INF=0x3f3f3f3f,mod=1e9+7;//998244353
int n,x,y,ans;
set<int>now[N];
int a[N],sz[N];
bool ban[N];
vector<int>E[N];
void dfs(int u,int fa,int w){
    bool ban=0;
    now[u].insert(w);
    for(auto &v:E[u]){
        if(v==fa)continue;
        dfs(v,u,w^a[v]);
        if(now[u].size()<now[v].size())now[u].swap(now[v]);
        for(auto &x:now[v]){
            if(now[u].count(x^a[u])){
                ban=1;
                break;
            }
        }
        for(auto &x:now[v]){
            now[u].insert(x);
        }
        now[v].clear();
    }
    if(ban){
        now[u].clear();
        ans++;
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
    }
    for(int i=2;i<=n;++i){
        scanf("%d%d",&x,&y);
        E[x].push_back(y);//E[i].pb(P(fa,w));
        E[y].push_back(x);//E[i].pb(P(fa,w));
    }
    dfs(1,0,a[1]);
    printf("%d\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小衣同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值