Luogu P4592 [TJOI2018]异或 做题记录
随机跳的。
树上维护序列,显然树剖。维护异或,显然 01trie。
01trie 维护区间异或,显然可持久化一下。
看到时限很大,显然可以双 log。
于是跑一边树剖,再根据 id 暴力建一个 可持久化01trie,单操 \(\mathrm{O(\log n \log w)}\)
(当然可以树上差分优成 \(\mathrm{O(\log w)}\),但是不想写了。)
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#define rep(i, a, b) for (int i = (a); i <= (b); i ++ )
#define rop(i, a, b) for (int i = (a); i < (b); i ++ )
#define dep(i, a, b) for (int i = (a); i >= (b); i -- )
#define dop(i, a, b) for (int i = (a); i > (b); i -- )
using namespace std;
using LL = long long;
using PII = pair<int, int>;
using PLL = pair<LL, LL>;
int read() {
int f = 1, s = 0; char ch = getchar();
for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1;
for (; ch >= '0' && ch <= '9'; ch = getchar()) s = (s << 1) + (s << 3) + (ch ^ 48);
return s * f;
}
const int N = 100010, M = N << 1;
const long long INF = 1 << 30;
int h[N], e[M], ne[M], idx;
int n, m, w[N], nw[N], top[N];
int son[N], sz[N], id[N], cnt;
int fa[N], dep[N];
struct node {
node *s[2]; int maxid;
node() { s[0] = s[1] = NULL; maxid = 0; }
}*root[N], pool[N << 5], *tail; // 开个内存池会快很多诶
void add(int a, int b) {
e[ ++ idx] = b, ne[idx] = h[a], h[a] = idx;
}
// ------------ tree cut ----------------
void dfs1(int u, int father, int depth) {
dep[u] = depth, fa[u] = father, sz[u] = 1;
for (int i = h[u]; i; i = ne[i]) {
int j = e[i];
if (j == father) continue;
dfs1(j, u, depth + 1);
sz[u] += sz[j];
if (sz[son[u]] < sz[j]) son[u] = j;
}
}
void dfs2(int u, int t) {
top[u] = t, id[u] = ++ cnt, nw[cnt] = w[u];
if (son[u]) dfs2(son[u], t);
for (int i = h[u]; i; i = ne[i]) {
int j = e[i];
if (j == fa[u] || j == son[u]) continue;
dfs2(j, j);
}
}
// ------------- 01trie ---------------
void build() {
tail = pool;
node *u = root[0] = new(tail ++ ) node();
dep(i, 30, 0) u -> s[0] = new(tail ++ ) node(), u = u -> s[0];
}
void insert(int x) {
node *u = root[x] = new(tail ++ ) node(), *p = root[x - 1];
int v = nw[x];
dep(i, 30, 0) {
if (p) *u = *p;
u -> maxid = max(u -> maxid, x);
int t = (v >> i) & 1; u -> s[t] = new(tail ++ ) node();
u = u -> s[t]; p = p ? p -> s[t] : NULL;
}
u -> maxid = max(u -> maxid, x);
}
LL query(node *u, int x, int lim) {
dep(i, 30, 0) {
int t = (x >> i) & 1;
if (u -> s[t ^ 1] && u -> s[t ^ 1] -> maxid >= lim) u = u -> s[t ^ 1];
else u = u -> s[t];
}
return (LL)x ^ nw[u -> maxid];
}
LL query(int u, int v, int z) {
LL res = -INF;
while (top[u] != top[v]) {
if (dep[top[u]] < dep[top[v]]) swap(u, v);
res = max(res, query(root[id[u]], z, id[top[u]]));
u = fa[top[u]];
}
if (dep[u] < dep[v]) swap(u, v);
res = max(res, query(root[id[u]], z, id[v]));
return res;
}
int main() {
n = read(), m = read();
for (int i = 1; i <= n; i ++ )
w[i] = read();
for (int i = 1, a, b; i < n; i ++ ) {
a = read(), b = read();
add(a, b), add(b, a);
}
dfs1(1, -1, 1), dfs2(1, 1); build();
for (int i = 1; i <= n; i ++ )
insert(i);
while (m -- ) {
int op = read(), x = read(), y, z;
if (op == 1) {
z = read();
printf("%lld\n", query(root[id[x] + sz[x] - 1], z, id[x]));
}
else {
y = read(), z = read();
printf("%lld\n", query(x, y, z));
}
}
return 0;
}
Luogu P4592 [TJOI2018]异或 做题记录的更多相关文章
- 洛谷 P4592 [TJOI2018]异或 解题报告
P4592 [TJOI2018]异或 题目描述 现在有一颗以\(1\)为根节点的由\(n\)个节点组成的树,树上每个节点上都有一个权值\(v_i\).现在有\(Q\)次操作,操作如下: 1 x y:查 ...
- 退役II次后做题记录
退役II次后做题记录 感觉没啥好更的,咕. atcoder1219 历史研究 回滚莫队. [六省联考2017]组合数问题 我是傻逼 按照组合意义等价于\(nk\)个物品,选的物品\(\mod k\) ...
- FJOI2017前做题记录
FJOI2017前做题记录 2017-04-15 [ZJOI2017] 树状数组 问题转化后,变成区间随机将一个数异或一,询问两个位置的值相等的概率.(注意特判询问有一个区间的左端点为1的情况,因为题 ...
- UOJ 做题记录
UOJ 做题记录 其实我这么弱> >根本不会做题呢> > #21. [UR #1]缩进优化 其实想想还是一道非常丝播的题目呢> > 直接对于每个缩进长度统计一遍就好 ...
- project euler做题记录
ProjectEuler_做题记录 简单记录一下. problem 441 The inverse summation of coprime couples 神仙题.考虑答案为: \[\begin{a ...
- Sam做题记录
Sam做题记录 Hihocoder 后缀自动机二·重复旋律5 求一个串中本质不同的子串数 显然,答案是 \(\sum len[i]-len[fa[i]]\) Hihocoder 后缀自动机三·重复旋律 ...
- 退役IV次后做题记录
退役IV次后做题记录 我啥都不会了.... AGC023 D 如果所有的楼房都在\(S\)同一边可以直接得出答案. 否则考虑最左最右两边的票数,如果左边>=右边,那么最右边会投给左边,因为就算车 ...
- 退役III次后做题记录(扯淡)
退役III次后做题记录(扯淡) CF607E Cross Sum 计算几何屎题 直接二分一下,算出每条线的位置然后算 注意相对位置这个不能先搞出坐标,直接算角度就行了,不然会卡精度/px flag:计 ...
- BJOI做题记录
BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...
- [日记&做题记录]-Noip2016提高组复赛 倒数十天
写这篇博客的时候有点激动 为了让自己不颓 还是写写日记 存存模板 Nov.8 2016 今天早上买了两个蛋挞 吃了一个 然后就做数论(前天晚上还是想放弃数论 但是昨天被数论虐了 woc noip模拟赛 ...
随机推荐
- Go 项目代码布局
Go 项目代码布局 目录 Go 项目代码布局 一.Go 语言"创世项目"结构 1.1 src 目录结构三个特点 二.Go 项目布局演进 2.1 演进一:Go 1.4 版本删除 pk ...
- Langchain-Chatchat项目:1-整体介绍
基于Langchain与ChatGLM等语言模型的本地知识库问答应用实现.项目中默认LLM模型改为THUDM/chatglm2-6b[2],默认Embedding模型改为moka-ai/m3e-b ...
- macbook-键盘连击问题002
https://support.apple.com/zh-cn/HT205662 如何清洁 MacBook 或 MacBook Pro 的键盘 如果您的 MacBook(2015 年及更新机型)或 M ...
- 重温dp——最长上升公共子序列
一道经典的dp了 题目描述 给出 1,2,-,n 的两个排列 P1 和 P2 ,求它们的最长公共子序列. 输入格式 第一行是一个数 n. 接下来两行,每行为 n 个数,为自然数 1,2,-,n 的一 ...
- 如何为你的WSL2更换最新的6.5.7kernel
1.如果你像我一样,喜欢折腾你的 WSL2 ,这里是安装内核 6.X 的方法. 2.这是一个坏主意,可能会导致系统不稳定.数据损坏和其他问题.也可能会没事的,但不要怪我. Arch linux的wsl ...
- 自研、好用、够快、稳定、代码可读性强的ORM
Fast Framework 作者 Mr-zhong 代码改变世界.... 一.前言 Fast Framework 基于NET6.0 封装的轻量级 ORM 框架 支持多种数据库 SqlServer O ...
- 合并果子(lgP1090)
贪心. 每次取最小的两堆合并,最后即为正确答案.(我也不会证明/wq) 所以说主要问题就是怎么找最小的两堆. 由于中间不断有插入和删除,所以用优先队列. 扯不下去了 直接看代码吧. #include& ...
- CF48C [The Race]
Problem 题目简述 现有 \(n\) 个已经加过油的加油站,如果当前剩余油量 \(< 10\) 升,则会加 \(x\) 升的油. 初始状态下,有 \(x\) 升油.每个加油站之间的距离为 ...
- 交互式数据分析和python笔记
1.安装conda 类似npm的n https://www.jianshu.com/p/544a4c8a8186 # 安装python 以及依赖 conda create -n joy python= ...
- 4个LED流水灯
#include "reg52.h" //此文件中定义了单片机的一些特殊功能寄存器 #include<intrins.h> //因为要用到左右移函数,所以加入这个头文件 ...