字符串训练之三

字符串训练三

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 node{int 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;
}

原文地址:https://www.cnblogs.com/wzxbeliever/p/11621318.html

时间: 2024-10-11 02:06:46

字符串训练之三的相关文章

字符串训练之一

字符串训练 例题一 https://www.luogu.org/problem/P2292 给出 N个单词,和 M 个句子,问每个句子中包含这些单词的最长前缀是多少. 解题技巧: 提取关键字:句子......前缀..... 好的学过AC自动机的就应该知道了 但现在有要求是最长 又是个最值问题:dp?贪心? 在ac自动机中唯一能插入其他操作的只有查询fail数组的时候才行 此时问题已经解决了一大半了 核心来了 for(int y=x;y;y=fail[y]) if(is_end[y]&&ex

python字符串学习之三

1.ord(),把字符转换为其对应的ASCII码 chr(),把ASCII码转换成相应的字符 例子:将一个二进制数的字符串转换为等值的十进制数 2.字符串修改: 字符串具有不可改变的特性,在创建后,不能改变:如果想要修改,那么,可以建立一个新的字符串并且以同一个变量名对其进行赋值 也可以采用replace()函数来修改:

字符串训练之四

https://www.luogu.org/problem/P2264 看一眼就是水题 方法应该很多,都可以乱搞出来 我就找了两个比较好的做法 一个是trie,还有一个是set trie #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<stack> #include<map> #inc

图论训练之三

https://www.luogu.org/problem/P2149 算是找到了一道好题吧 看样例直接提醒我们两点间的最短路可能不止一条 看套路: 如何判断一条边是否在这两点(S,T)最短路径上 solution:S跑一遍単源最短路,T跑一遍単源最短路,再枚举边,判断!!!!! 至于为什么要跑两遍,很好理解,因为他是単源最短路, 自行体会,实在不行看代码就懂了 同理这一道题,分别四个点跑一次単源最短路,判断两次就可以 但问题来了,因为最短路可能不止一条, 这样你就不可能把所以成立的边都加起来

杂题训练之三

https://www.luogu.org/problem/P1858 模板题,套路东西,思路代码里,很清晰,很明了 code : #include<bits/stdc++.h> #define IL inline #define RI register int using namespace std; IL void in(int &x) { int f=1;x=0;char s=getchar(); while(s>'9' or s<'0'){if(s=='-')f=-

bash脚本编程之字符串操作

字符串操作之一:测试变量存在性 ${varname:-word} 如果varname存在且非null,返回其值,否则返回word ${varname:=word} 如果varname存在且非null,返回其值,否则将其设置为word,然后返回其值 ${varname:?message} 如果varname存在且非null,返回其值,否则打印varname:后跟message,并退出当前命令或脚本 ${varname:+word} 如果varname存在且非null,返回word,否则返回null

Android基础入门教程——8.3.14 Paint几个枚举-常量值以及ShadowLayer阴影效果

Android基础入门教程--8.3.14 Paint几个枚举/常量值以及ShadowLayer阴影效果 标签(空格分隔): Android基础入门教程 本节引言: 在Android基础入门教程--8.3.1 三个绘图工具类详解Paint的方法参数那里我们就接触到 了这样几个东西:Paint.Style,Paint.Cap,Paint.Join等,这些都是Paint中的一些枚举值,相关 方法我们可以通过设置这些枚举值来设置特定效果比如:Style:画笔样式,Join图形结合方式等, 本节我们走进

Android Metrics

Ref:Android的单位以及屏幕分辨率详解 Ref:Android中dp,px,sp概念梳理以及如何做到屏幕适配 Ref:Android多屏幕适配 Ref:Android字符串进阶之三:字体属性及测量(FontMetrics)

C++ 字符串编程训练1

最近又到了找工作的时间,所以想每天抽点时间出来对编程进行相关训练.C++字符串是一个很重要的知识点,采用STL.算法等C++优于C的方面,能够使问题解决起来更加轻松.以下程序都是自己写的,可能有些地方时间效率.空间效率不高,所以希望大家能够多多讨论交流,互相提升. 题目:删除子串 说明:给定两个形参str和substr,其中str为源字符串,substr为需要删除的子串,如果str中包含substr,则将其删除并输出新的字符串,否则输出源字符串. void delete_substr(strin