czr 太弱啦

探讨如何解决树形结构中寻找特定异或和路径的问题,通过深度优先搜索算法和哈希表辅助,实现对边权进行异或运算并计数的高效算法。

题目描述
czr太弱啦!他现在小学组题目都不会做,于是来求助你。
问题是:给定一棵树,问路径的异或和等于k的有几条?
形式化描述:给定一棵N个节点组成的有边权的无根树,你需要计数这样的正整数对(u,v)(1≤u≤v≤n),满足若从u到v经过的路径上的边权依次为w1,w2,…,wL,那么w1 xor w2 xor…xor wL =k。其中“xor”表示非负整数按位取异或。

输入
第1行:两个正整数n,k,含义见题面描述。
第2∼n行:每一行包含三个正整数u,v,w,代表节点u、v之间存在一条权值为w的边。节点从1开始编号。

输出
第1行:一个正整数——所有路径中异或和为k的路径条数。

样例输入
5 0
4 3 7
5 1 4
3 2 7
5 4 7

样例输出
2

提示
有2–3–4、3–4–5共2条路径上的边权异或和为k=0。
对于所有测试数据,所有权值w满足0≤w≤231−1。
在这里插入图片描述
思路
给了5s的时限,建树暴力求解即可,由于xor具有x xor z xor y xor z= k 的性质,因此只需要从任意根节点出发,求解时查询已经该数xork求得的数量即可

代码实现

#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N=2e6+10;
const int mod=1e9+7;
const int INF=0x3f3f3f;
typedef pair<int,int> P;

struct edge
{
    int v,index,val;
}Edge[N];

int n,head[N];
int cnt,k;
ll ans;
bool vis[N];
map<int,int> p;
void add(int u,int v,int val)
{
    Edge[++cnt].v=v;
    Edge[cnt].index=head[u];
    Edge[cnt].val=val;
    head[u]=cnt;
}

void dfs(int x,int nu)
{
    if(vis[x]) return ;
    vis[x]=true;
    ans=ans+p[nu^k];
    p[nu]++;  //记录与k异或相同的数字
    for(int i=head[x];i;i=Edge[i].index)
    {
        int v=Edge[i].v;
        dfs(v,nu^Edge[i].val);
    }
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1;i<n;i++)
    {
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        add(u,v,w),add(v,u,w);
    }
    dfs(1,0);
    printf("%lld\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值