Description

现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\)。现在有\(Q\)次操作,操作如下:

  • 1\(\;x\;y\):查询节点\(x\)的子树中与\(y\)异或结果的最大值
  • 2\(\;x\;y\;z\):查询路径\(x\)到\(y\)上点与\(z\)异或结果最大值

Input

第一行是两个数字\(n,Q\);

第二行是\(n\)个数字用空格隔开,第\(i\)个数字\(v_i\)表示点\(i\)上的权值

接下来\(n-1\)行,每行两个数,\(x,y\),表示节点\(x\)与\(y\)之间有边

接下来\(Q\)行,每一行为一个查询,格式如上所述.

Output

对于每一个查询,输出一行,表示满足条件的最大值。

表示不太会可持久化\(01Trie\)

参考着题解码了出来,还是有点不懂.

但是又感觉懂得差不多。

这个题差不多可以自己码出来,很好的一个题。

可持久化\(01Trie\)思想还行,类似于主席树思想.

用到了\(lastroot\).

对于现在的自己,不太想深究具体构造,感觉网上讲解的这个不是很好。

打算活过\(NOIP\)之后写一篇讲解。

代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#define R register using namespace std; const int maxn= 1e5+8; inline void in(int &x)
{
int f=1;x=0;char s=getchar();
while(!isdigit(s)){if(s=='-')f=-1;s=getchar();}
while(isdigit(s)){x=x*10+s-'0';s=getchar();}
x*=f;
} struct Trie
{
int root[maxn],ch[maxn*35][2],tot,cnt[maxn*35];
Trie(){root[0]=tot=1;}
inline void insert(int lastroot,int &nowroot,int x)
{
nowroot=++tot;
int u=nowroot;
for(R int i=30;~i;i--)
{
R int bit=(x>>i)&1;
ch[u][!bit]=ch[lastroot][!bit];
ch[u][bit]=++tot;
u=ch[u][bit];
lastroot=ch[lastroot][bit];
cnt[u]=cnt[lastroot]+1;
}
} inline int query(int l,int r,int x)
{
int res=0;
for(R int i=30;~i;i--)
{
R int bit=(x>>i)&1;
if(cnt[ch[r][!bit]]-cnt[ch[l][!bit]])
{
r=ch[r][!bit];
l=ch[l][!bit];
res+=(1<<i);
}
else
{
r=ch[r][bit];
l=ch[l][bit];
}
}
return res;
}
}tr,se; int dfn[maxn],fdfn[maxn],val[maxn],idx,depth[maxn]; int head[maxn],tot,l[maxn],r[maxn],size[maxn];
struct cod{int u,v;}edge[maxn<<1]; inline void add(R int x,R int y)
{
edge[++tot].u=head[x];
edge[tot].v=y;
head[x]=tot;
} int f[maxn][21]; void dfs(R int u,R int fa)
{
tr.insert(tr.root[fa],tr.root[u],val[u]);
f[u][0]=fa;depth[u]=depth[fa]+1;
dfn[u]=++idx,fdfn[idx]=u;size[u]=1;
for(R int i=1;(1<<i)<=depth[u];i++)
f[u][i]=f[f[u][i-1]][i-1];
for(R int i=head[u];i;i=edge[i].u)
{
if(edge[i].v==fa)continue;
dfs(edge[i].v,u);
size[u]+=size[edge[i].v];
}
} inline int lca(R int x,R int y)
{
if(depth[x]>depth[y])swap(x,y);
for(R int i=17;~i;i--)
if(depth[x]+(1<<i)<=depth[y])
y=f[y][i];
if(x==y)return y;
for(R int i=17;~i;i--)
{
if(f[x][i]==f[y][i])continue;
x=f[x][i],y=f[y][i];
}
return f[x][0];
} int n,q; int main()
{
in(n),in(q);
for(R int i=1;i<=n;i++)in(val[i]);
for(R int i=1,x,y;i<n;i++)
{
in(x),in(y);
add(x,y),add(y,x);
}
dfs(1,0);
for(R int i=1;i<=n;i++)
se.insert(se.root[i-1],se.root[i],val[fdfn[i]]);
for(R int opt,x,y,z;q;q--)
{
in(opt);
if(opt==1)
{
in(x),in(y);
printf("%d\n",se.query(se.root[dfn[x]-1],se.root[dfn[x]+size[x]-1],y));
}
else
{
in(x),in(y),in(z);
int la=lca(x,y);
printf("%d\n",max(tr.query(tr.root[f[la][0]],tr.root[x],z),tr.query(tr.root[f[la][0]],tr.root[y],z)));
}
}
}

可持久化01Trie树+LCA【p4592】[TJOI2018]异或的更多相关文章

  1. 可持久化01Trie树【p4735(bzoj3261)】最大异或和

    Description 给定一个非负整数序列\(\{a\}\),初始长度为\(N\). 有\(M\)个操作,有以下两种操作类型: A x:添加操作,表示在序列末尾添加一个数\(x\),序列的长度\(N ...

  2. 洛谷 P4592 [TJOI2018]异或 解题报告

    P4592 [TJOI2018]异或 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1 x y:查 ...

  3. 可持久化0-1Trie树

    我跟可持久化数据结构杠上了 \(QwQ\) .三天模拟赛考了两次可持久化数据结构(主席树.可持久化0-1Trie树),woc. 目录: 个人理解 时空复杂度分析 例题及简析 一.个人理解 可持久化0- ...

  4. bzoj 4137 [FJOI2015]火星商店问题——线段树分治+可持久化01trie树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4137 关于可持久化01trie树:https://www.cnblogs.com/LadyL ...

  5. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

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

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

  7. 洛谷P4592 [TJOI2018]异或(可持久化01Trie)

    题意 题目链接 可持久化01Trie板子题 对于两个操作分别开就行了 #include<bits/stdc++.h> using namespace std; const int MAXN ...

  8. 洛谷P4592 [TJOI2018]异或 【可持久化trie树】

    题目链接 BZOJ4592 题解 可持久化trie树裸题 写完就A了 #include<algorithm> #include<iostream> #include<cs ...

  9. BZOJ 3261: 最大异或和位置-贪心+可持久化01Trie树

    3261: 最大异或和 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 3519  Solved: 1493[Submit][Status][Discu ...

随机推荐

  1. 与http协作的web服务器、http首部(第五章、第六章)

    第五章 与http协作的web服务器 1.用单台虚拟主机实现多个域名 通过域名访问主机,经过DNS解析成ip地址,反向代理,可以代理多台服务器,正向代理则相反,代理客户端 2.通信数据转化程序:代理. ...

  2. PHP 截取字符串,多余部分用 ........ 代替

    /** * 参数说明 * $string 欲截取的字符串 * $sublen 截取的长度 * $start 从第几个字节截取,默认为0 * $code 字符编码,默认UTF-8 */ function ...

  3. 解决SpringSecurity限制iframe引用页面的问题

    使用Spring Security的过程中,需要使用iframe来引入其他域的页面,页面会报X-Frame-Options的错误,试了好几种方法一直未能很好的解决这个问题. 这里涉及到Spring S ...

  4. unity ugui缩放+移动

    本文仅仅记录自己在工作中踩到的ugui的坑.并讲述如何填的坑. 干货罗列在前,不愿意看的,拿东西走人,自己研究: RectTransform m_Rect m_Rect.localPosition m ...

  5. hdu 1253 胜利大逃亡(简单题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1253 题目大意:在所给的时间能顺利离开城堡. #include <iostream> #i ...

  6. 类图(Class Diagram)

    类图(Class Diagram): 类(Class)封装了数据和行为,是面向对象的重要组成部分,它是具有相同属性.操作.关系的对象集合的总称. 类一般由三部分组成: 类名(Class):每个类都必须 ...

  7. peepscan前期准备工作

    具有的功能 1.whoami 2.sub doamin https://dns.aizhan.com/huayi-faucet.com/ 3.dir scan 4.web server 5.port ...

  8. Linux进程的创建函数fork()及其fork内核实现解析

    进程的创建之fork() Linux系统下,进程可以调用fork函数来创建新的进程.调用进程为父进程,被创建的进程为子进程. fork函数的接口定义如下: #include <unistd.h& ...

  9. 看jquery3.3.1学js类型判断的技巧

    需要预习:call , typeof, js数据类型 1. isFunction中typeof的不靠谱 源码: var isFunction = function isFunction( obj ) ...

  10. selenium WebElement 的属性和方法 属性

    tag_name 标签名,例如 'a'表示<a>元素get_attribute(name) 该元素name 属性的值text 该元素内的文本,例如<span>hello< ...