D33 树上启发式合并 CF1709E XOR Tree

视频链接:331 树上启发式合并 CF1709E XOR Tree_哔哩哔哩_bilibili

 

 

 

Luogu CF1709E XOR Tree

复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

const int N=200010;
int n,ans,a[N];
int dis[N]; //dis[x]从根到x的异或和
vector<int> e[N]; //邻接点
set<int> s[N]; //s[x]:x子树内各点的dis集合

void dfs(int x,int fa){
  s[x].insert(dis[x]);
  
  bool flag=0;
  for(int y:e[x]){
    if(y==fa) continue;
    dis[y]=dis[x]^a[y];
    dfs(y,x);
    
    if(s[x].size()<s[y].size()) swap(s[x],s[y]);
    
    for(int z:s[y]) //如果s[x]中存在s[y]^a[x]
      if(s[x].find(z^a[x]) != s[x].end()) flag=1;
    for(int z:s[y]) s[x].insert(z); //s[y]并入s[x]
  }
  
  if(flag) ans++, s[x].clear(); //x子树已无贡献
}
int main(){
  scanf("%d",&n);
  for(int i=1; i<=n; i++) scanf("%d",&a[i]);
  for(int i=1; i<n; i++){
    int x,y; scanf("%d%d",&x,&y);
    e[x].push_back(y); e[y].push_back(x);
  }
  dis[1]=a[1];
  dfs(1, 0);
  printf("%d\n",ans);
}
复制代码

 

复制代码
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <set>
using namespace std;

const int N=2e5+10;
int n,ans,a[N];
int siz[N],son[N],dis[N];
vector<int> e[N];
set<int> s[N];
 
void dfs1(int x,int fa){ //搞son,dis
  dis[x]=dis[fa]^a[x];
  siz[x]=1;
  for(int y:e[x]){
    if(y==fa) continue;
    dfs1(y,x);
    siz[x]+=siz[y];
    if(siz[y]>siz[son[x]]) son[x]=y;
  }
}
void dfs2(int x,int fa){
  if(son[x]){ //先搜重儿子
    dfs2(son[x],x);
    swap(s[son[x]],s[x]); //s[x]指向大集合
  }
  bool flag=0;
  if(s[x].find(dis[x]^a[x]) != s[x].end()) flag=1;
  s[x].insert(dis[x]); //dis[x]插入s[x]
  
  for(int y:e[x]){ //后搜轻儿子
    if(y==son[x] || y==fa) continue;
    dfs2(y,x);
    
    for(int z:s[y]) //如果s[x]中存在s[y]^a[x]
      if(s[x].find(z^a[x]) != s[x].end()) flag=1;
    for(int z:s[y]) s[x].insert(z); //s[y]并入s[x]
  }
  
  if(flag) ++ans,s[x].clear(); //x子树已无贡献
}
int main(){
  scanf("%d",&n);
  for(int i=1; i<=n; i++) scanf("%d",&a[i]);
  for(int i=1; i<n; i++){
    int x,y; scanf("%d%d",&x,&y);
    e[x].push_back(y); e[y].push_back(x);
  }
  dfs1(1,0);
  dfs2(1,0);
  printf("%d\n",ans);
}
View Code
复制代码

 

练习:

Luogu CF741D Arpa’s letter-marked tree and Mehrdad’s Dokhtar-kosh paths

 

posted @   董晓  阅读(374)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
历史上的今天:
2022-08-08 C09【模板】可持久化字典树(Trie)
点击右上角即可分享
微信分享提示