题面

BZOJ

Sol

显然是要维护一个区域的 \(trie\) 树,然后贪心

区间 \(trie\) 树???

可持久化 \(trie\) 树???

直接参考主席树表示出区间的方法建立 \(trie\) 树,然后做差就好了

巨简单

# include <bits/stdc++.h>
# define IL inline
# define RG register
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll; IL int Input(){
RG int x = 0, z = 1; RG char c = getchar();
for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
return x * z;
} const int maxn(1e5 + 5);
const int pw(1 << 30); int n, q, first[maxn], cnt, val[maxn], dfn[maxn], idx, id[maxn];
int size[maxn], son[maxn], top[maxn], deep[maxn], fa[maxn]; struct Edge{
int to, next;
} edge[maxn << 1]; struct Trie{
int ch[2][maxn * 32], rt[maxn], tot, sz[maxn * 32]; IL void Modify(RG int &x, RG int v, RG int d){
ch[0][++tot] = ch[0][x], ch[1][tot] = ch[1][x];
sz[tot] = sz[x] + 1, x = tot;
if(!d) return;
Modify(ch[bool(d & v)][x], v, d >> 1);
} IL int Query1(RG int a, RG int b, RG int v, RG int dep){
if(!a || !dep) return 0;
RG int f = bool(dep & v) ^ 1, s = sz[ch[f][a]] - sz[ch[f][b]];
if(s) return Query1(ch[f][a], ch[f][b], v, dep >> 1) + dep;
f ^= 1;
return Query1(ch[f][a], ch[f][b], v, dep >> 1);
} IL int Query2(RG int a, RG int b, RG int c, RG int d, RG int v, RG int dep){
if(!(a + b) || !dep) return 0;
RG int f = bool(dep & v) ^ 1, s = sz[ch[f][a]] + sz[ch[f][b]] - sz[ch[f][c]] - sz[ch[f][d]];
if(s) return Query2(ch[f][a], ch[f][b], ch[f][c], ch[f][d], v, dep >> 1) + dep;
f ^= 1;
return Query2(ch[f][a], ch[f][b], ch[f][c], ch[f][d], v, dep >> 1);
}
} tree1, tree2; IL void Add(RG int u, RG int v){
edge[cnt] = (Edge){v, first[u]}, first[u] = cnt++;
} IL void Dfs1(RG int u, RG int ff){
size[u] = 1, tree1.rt[u] = tree1.rt[ff];
tree1.Modify(tree1.rt[u], val[u], pw);
for(RG int e = first[u]; e != -1; e = edge[e].next){
RG int v = edge[e].to;
if(v != ff){
deep[v] = deep[u] + 1, fa[v] = u;
Dfs1(v, u);
size[u] += size[v];
if(size[v] > size[son[u]]) son[u] = v;
}
}
} IL void Dfs2(RG int u, RG int tp){
dfn[u] = ++idx, id[idx] = u, top[u] = tp;
if(son[u]) Dfs2(son[u], tp);
for(RG int e = first[u]; e != -1; e = edge[e].next)
if(!dfn[edge[e].to]) Dfs2(edge[e].to, edge[e].to);
} IL int LCA(RG int u, RG int v){
while(top[u] ^ top[v])
deep[top[u]] > deep[top[v]] ? u = fa[top[u]] : v = fa[top[v]];
return deep[u] > deep[v] ? v : u;
} int main(){
n = Input(), q = Input();
for(RG int i = 1; i <= n; ++i) val[i] = Input(), first[i] = -1;
for(RG int i = 1; i < n; ++i){
RG int u = Input(), v = Input();
Add(u, v), Add(v, u);
}
Dfs1(1, 0), Dfs2(1, 0);
for(RG int i = 1; i <= n; ++i){
tree2.rt[i] = tree2.rt[i - 1];
tree2.Modify(tree2.rt[i], val[id[i]], pw);
}
for(RG int i = 1; i <= q; ++i)
if(Input() == 1){
RG int u = Input(), v = Input();
printf("%d\n", tree2.Query1(tree2.rt[dfn[u] + size[u] - 1], tree2.rt[dfn[u] - 1], v, pw));
}
else{
RG int u = Input(), v = Input(), x = Input(), lca = LCA(u, v);
printf("%d\n", tree1.Query2(tree1.rt[u], tree1.rt[v], tree1.rt[lca], tree1.rt[fa[lca]], x, pw));
}
return 0;
}

可持久化trie(BZOJ5338: [TJOI2018]xor)的更多相关文章

  1. [BZOJ5338][TJOI2018]xor(可持久化Trie)

    可持久化Trie模板题. 建两种可持久化Trie,每个点两棵,一棵对DFS求前缀和,一棵对祖先求前缀和. 或者树剖,不好写多少还多个log. #include<cstdio> #inclu ...

  2. BZOJ5338 [TJOI2018] Xor 【可持久化Trie树】【dfs序】

    题目分析: 很无聊的一道题目.首先区间内单点对应异或值的询问容易想到trie树.由于题目在树上进行,case1将路径分成两段,然后dfs的时候顺便可持久化trie树做询问.case2维护dfs序,对d ...

  3. [BZOJ5338][TJOI2018]xor

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

  4. BZOJ5338[TJOI2018]xor——主席树+dfs序

    题目描述 现在有一颗以1为根节点的由n个节点组成的树,树上每个节点上都有一个权值vi. 现在有Q 次操作,操作如下: 1  x y    查询节点x的子树中与y异或结果的最大值 2 x y z     ...

  5. BZOJ.5338.[TJOI2018]xor(可持久化Trie)

    BZOJ LOJ 洛谷 惊了,18年了还有省选出模板题吗= = 做这题就是练模板的,我就知道我忘的差不多了 询问一就用以DFS序为前缀得到的可持久化Trie做,询问二很经典的树上差分. 注意求询问二的 ...

  6. [TJOI2018] Xor 异或 (可持久化Trie,树链剖分)

    题目描述 现在有一颗以 1 为根节点的由 n 个节点组成的树,树上每个节点上都有一个权值 \(v_i\).现在有 Q 次操作,操作如下: 1 x y :查询节点 x 的子树中与 y 异或结果的最大值. ...

  7. 51nod1295 XOR key(可持久化trie)

    1295 XOR key题目来源: HackerRank基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题 给出一个长度为N的正整数数组A,再给出Q个查询,每个查 ...

  8. 51nod 1295 XOR key (可持久化Trie树)

    1295 XOR key  题目来源: HackerRank 基准时间限制:1.5 秒 空间限制:262144 KB 分值: 160 难度:6级算法题   给出一个长度为N的正整数数组A,再给出Q个查 ...

  9. 【xsy1147】 异或(xor) 可持久化trie

    我的脑回路可能比较奇怪. 我们对这些询问离线,将所得序列${a}$的后缀和建$n$棵可持久化$trie$. 对于一组询问$(l,r,x)$,我们在主席树上询问第$l$棵树$-$第r$+1$棵树中与$s ...

随机推荐

  1. 本机号码认证黑科技:极光(JG)开发者服务推出“极光认证”新产品

    近日,中国领先的大数据服务商极光(JG)推出全新产品--极光认证JVerification.极光认证是极光针对APP用户注册登陆,二次安全验证等身份验证场景打造的一款本机号码认证SDK,验证用户提供的 ...

  2. P4382 [八省联考2018]劈配

    题目链接 题意分析 受到了\(olinr\ \ julao\)的影响 写了匈牙利算法 首先 我们对于每一个人 从高到低枚举志愿 如果当前志愿的老师有剩余的话 那么我们就选 否则的话 我们看看谁的那个志 ...

  3. Es6 类class的关键 super、static、constructor、new.target

    ES6引入了Class(类)这个概念,作为对象的模板,通过class关键字,可以定义类.基本上,ES6的class可以看作只是一个语法糖,它的绝大部分功能,ES5都可以做到,新的class写法只是让对 ...

  4. leetcode-350-Intersection of Two Arrays II(求两个数组的交集)

    题目描述: Given two arrays, write a function to compute their intersection. Example:Given nums1 = [1, 2, ...

  5. LeetCode 795. Number of Subarrays with Bounded Maximum

    问题链接 LeetCode 795 题目解析 给定一个数组A,左右范围L.R.求子数组的数量,要求:子数组最大值在L.R之间. 解题思路 子数组必须连续,利用最大值R对数组进行分段,设定变量 left ...

  6. C 语言调试信息输出宏定义

    C 语言经常在实际的调试过程中,使用最基本的调试方法printf,我们可以使用__FILENAME__.__FUNCTION__.__LINE__,增加自己的输出宏定义: #define DVR_PR ...

  7. Mac 10.12安装WebStorm

    下载: (链接: https://pan.baidu.com/s/1c2o8wUG 密码: 2waz)

  8. Mac下锁屏快捷键

    ▲先设置“进入眨眼或开始屏幕保护程序”选择”立即“要求输入密码. [系统编好设置]->[通用] ▲通过快捷键[shift+control+光驱键]或者[option+command+关机键]

  9. C# 文件操作系列一

    在.Net环境中,所有关于文件操作的类都在System.IO命名空间下,注:在修改文件时,安全性显得格外重要,但是本随笔不过多讲述安全性,这里假设我们有足够的权限. 1.管理文件系统 先通过一幅图来了 ...

  10. JavaScript数据结构-16.二叉树计数

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...