Tree

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 2058    Accepted Submission(s): 599

Problem Description
  Zero and One are good friends who always have fun with each other. This time, they decide to do something on a tree which is a kind of graph that there is only one path from node to node. First, Zero will give One an tree and every node in this tree has a value. Then, Zero will ask One a series of queries. Each query contains three parameters: x, y, z which mean that he want to know the maximum value produced by z xor each value on the path from node x to node y (include node x, node y). Unfortunately, One has no idea in this question. So he need you to solve it.
 
Input
  There are several test cases and the cases end with EOF. For each case:

The first line contains two integers n(1<=n<=10^5) and m(1<=m<=10^5), which are the amount of tree’s nodes and queries, respectively.

The second line contains n integers a[1..n] and a[i](0<=a[i]<2^{16}) is the value on the ith node.

The next n–1 lines contains two integers u v, which means there is an connection between u and v.

The next m lines contains three integers x y z, which are the parameters of Zero’s query.

 
Output
  For each query, output the answer.
 
Sample Input
3 2
1 2 2
1 2
2 3
1 3 1
2 3 2
 
Sample Output
3
0
 
先放模仿代码,我是先6191不会做然后学了一下。。
 题意:路径u->v上与x异或的最大值是多少
 
我觉得这个可持续字典树的写法有点像AC自动机的意思,他没有的son就相当于失配指针,从而跳到前面有的地方
 
先用0作为一个源节点,然后用LCA搞一下分两步,分别求LCA(u,v)的父节点到u和到v的值,哪个大取哪个就OK了。
 
#include<cstdio>
#include<cstring>
#include<algorithm>
const int N=100008;
int a[N],head[N],tot,index,cont,n,m;
int root[N],tree[N*35][2],son[N*35][2];
int fa[N],depth[N],up[N][18],pt[N];
struct node{
   int next,to;
}e[N<<1];
void add(int u,int v){
   e[tot].next=head[u];e[tot].to=v;head[u]=tot++;
   e[tot].next=head[v];e[tot].to=u;head[v]=tot++;
}
void build(int last,int cur,int num,int pos){
   if(pos<0) return;
   int temp=!!(num&(1<<pos));
   tree[cur][temp]=tree[last][temp]+1;
   son[cur][temp^1]=son[last][temp^1];
   tree[cur][temp^1]=tree[last][temp^1];
   build(son[last][temp],son[cur][temp]=++cont,num,pos-1);//这里可以看到每一个数字都建立了31个节点,其实只要17个就够了根据题意
}
void dfs(int u){
   pt[u]=++index;//记录一下每个节点在树中的位置
   build(root[pt[fa[u]]],root[pt[u]]=++cont,a[u],31);
   for(int i=head[u];~i;i=e[i].next){
    int v=e[i].to;
    if(fa[u]==v) continue;
    fa[v]=u;
    depth[v]=depth[u]+1;
    dfs(v);
   }
}
void doit(){
    for(int i=1;i<=n;++i) up[i][0]=fa[i];
    for(int j=1;j<=16;++j) for(int i=1;i<=n;++i) up[i][j]=up[up[i][j-1]][j-1];
}
int lca(int x,int y){
    if(depth[x]<depth[y]) std::swap(x,y);
    int dt=depth[x]-depth[y];
    for(int i=0;i<=16;++i) if(dt&(1<<i)) x=up[x][i];
    if(x==y) return x;
    for(int i=16;i>=0;--i) if(up[x][i]!=up[y][i]) x=up[x][i],y=up[y][i];
    return up[x][0];
}
int query(int last,int cur,int num,int sum,int pos){
   if(pos<0) return sum;
   int temp=!!(num&(1<<pos));
   if(tree[cur][temp^1]-tree[last][temp^1]>0) return query(son[last][temp^1],son[cur][temp^1],num,sum|(1<<pos),pos-1);
   else return query(son[last][temp],son[cur][temp],num,sum,pos-1);
}
int main(){
   int x,y,z;
   while(scanf("%d%d",&n,&m)!=EOF){
    memset(head,-1,sizeof(head));
    index=tot=cont=0;
    for(int i=1;i<=n;++i) scanf("%d",&a[i]);
    for(int i=1;i<n;++i) {scanf("%d%d",&x,&y);add(x,y);}
    dfs(1);
    doit();
    while(m--){
        scanf("%d%d%d",&x,&y,&z);
        int ct=lca(x,y);
        int mx=query(root[pt[fa[ct]]],root[pt[x]],z,0,31);
        mx=std::max(query(root[pt[fa[ct]]],root[pt[y]],z,0,31),mx);
        printf("%d\n",mx);
    }
   }
}
 
 

hdu4757 可持续字典树的更多相关文章

  1. 可持续字典树 Perfect Security

    题目链接 题目大意:给你两个序列,第二个序列可以任意进行排列变换,然后由这两个序列一一异或得到答案序列,要求答案序列的字典序最小. 可持续字典树与第K大可持续线段树的区别主要在于每个节点上 ,它多了一 ...

  2. Hdu-4757 Tree(可持久化字典树+lca)

    题目链接:点这 我的github地址:点这     Problem Description   Zero and One are good friends who always have fun wi ...

  3. [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...

  4. 9-11-Trie树/字典树/前缀树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第9章  查找 - Trie树/字典树/前缀树(键树) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚 ...

  5. [LeetCode] 208. Implement Trie (Prefix Tree) 实现字典树(前缀树)

    Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie. ...

  6. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  7. 字典树+博弈 CF 455B A Lot of Games(接龙游戏)

    题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...

  8. 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)

    萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...

  9. 山东第一届省赛1001 Phone Number(字典树)

    Phone Number Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 We know that if a phone numb ...

随机推荐

  1. QQ网站的源代码

    链接:https://pan.baidu.com/s/1mqetTbauKTI0KJOaU8wW5A 提取码请加QQ:2669803073获取 声明:仅供学习,切勿用于其他用途

  2. 【EditPlus】参数设置

    1. 设置javac,java快捷键 工具-参数设置-工具-用户工具 组和工具项-组名,更改组名为“java” 添加工具 javac 菜单文字:javac 命令:安装java的javac.exe的绝对 ...

  3. web前端项目中遇到的一些问题总结(08.23更新)

    个人网站 https://iiter.cn 程序员导航站 开业啦,欢迎各位观众姥爷赏脸参观,如有意见或建议希望能够不吝赐教! 写一些最近工作中Vue项目中遇到的问题. 巴啦啦小魔仙,污卡拉,全身变,小 ...

  4. 源码阅读:Masonry(三)—— MASViewAttribute

    该文章阅读的 Masonry 的版本为 1.1.0. 这个类我们可以叫它"约束视图及其属性类",它封装了设置约束的视图和其设置约束的属性,也就是 view1 和 attr1,或是 ...

  5. Java 数组 之 二维数组

    转载于 : http://www.verejava.com/?id=16992693216433 public class BinaryArray { public static void main( ...

  6. 《Docker从入门到跑路》之网络模型介绍

    Bridge模式 当我们安装完docker后,启动Docker daemon,就会在主机上看到一个docker0的网桥,默认在此主机上启动的容器都会连接到这个网桥上.虚拟网桥的工作方式和物理交换机的工 ...

  7. EditPlus编辑java代码 常规配置

  8. Qt for Android (三) 打开Android相册并选一个图片进行显示

    Qt for Android (三) 这两天弄了一下android相册的相关功能.还是花了挺长时间的,这里总结一下,避免以后再踩坑.同时也在这篇文章里面补齐一些android开发的基础支持 打开And ...

  9. Dynamics 9.0 安装好后 公告出现 提示:出现错误。 请稍等片刻,然后重试。 如果问题仍然存在,请与管理员联系。

    此问题为系统的Bug,示例图如下: 解决方案为修改存储过程 p_RetrievePosts,将startDate参数的默认值改成 1900-01-01,endDate参数的默认值改成 9999-12- ...

  10. JAVA基础篇 之 finalize()方法的作用

    ​ 我们知道java有垃圾回收器负责回收无用对象占据的内存资源,但也有特殊情况:假设你的对象(并非使用new)获得了一块特殊的内存区域,由于垃圾回收器只知道回收那些经由new分配的内存,所以它不知道如 ...