字符串训练之三

Posted wzxbeliever

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了字符串训练之三相关的知识,希望对你有一定的参考价值。

字符串训练三

https://www.luogu.org/problem/P4551

题目描述:

给定一棵n个点的带权树,结点下标从1开始到N。寻找树中找两个结点,求最长的异或路径。

异或路径指的是指两个结点之间唯一路径上的所有边权的异或

分析:

嗯?这不是个图论题吗?什么狗屁字符串?

首先看到异或,那01trie树就必不可少的了

首先对一条边异或2次,相当于没有异或。

这样的话 i -> j 的异或和,就是 i -> 1 的异或和,再异或上 1 -> j 的异或和。

处理出每个点到1路径的异或和,然后找两个,使它们异或起来最大。

等等这不又是板子题吗?

找出两个异或最大(这个我前面两个练习有说)

于是直接套板子即可

code by wzxbeliever

#include<bits/stdc++.h>
#define ll long long
#define ri register int
#define il inline
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=100005;
int head[maxn],tr[maxn*31][2],w[maxn]; 
int n,ans,rt,cnt,tot;
struct nodeint to,next,w;edg[maxn<<1];
il void add(int u,int v,int w)++cnt;edg[cnt].next=head[u];edg[cnt].w=w;edg[cnt].to=v;head[u]=cnt;
il void bulid(int x,int rt)
     for(ri i=1<<30;i;i>>=1)bool c=x&i;
     if(!tr[rt][c])tr[rt][c]=++tot;
     rt=tr[rt][c];
     

il int query(int x,int rt)
     int ans=0; 
     for(ri i=1<<30;i;i>>=1)bool c=x&i;
     if(tr[rt][c^1])ans+=i,rt=tr[rt][c^1];
     else rt=tr[rt][c];
     return ans;

il void dfs(int u,int fa)
    for(ri i=head[u];i;i=edg[i].next)int to=edg[i].to;
    if(to==fa)continue;
    w[to]=w[u]^edg[i].w;dfs(to,u);
    

int main()

//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    scanf("%d",&n);
    for(ri i=1,u,v,w;i<n;i++)scanf("%d%d%d",&u,&v,&w),add(u,v,w),add(v,u,w);
    dfs(1,0);
    for(ri i=1;i<=n;i++)bulid(w[i],rt);
    for(ri i=1;i<=n;i++)ans=max(ans,query(w[i],rt));
    printf("%d\n",ans);
    return 0;

以上是关于字符串训练之三的主要内容,如果未能解决你的问题,请参考以下文章

动态规划训练之三

图论训练之三

性能调优之三十六计 —— 「优中取优」字符串拼接 篇

性能调优之三十六计 —— 「优中取优」字符串拼接 篇

python编程基础之三十八

论文写作分析之三《基于预训练语言模型的案件要素识别方法》