闲话 22.7.26
闲话
似乎有人被我的《其人》吸引了。感觉挺好。要不以后统计一个《其人》系列(
说到ACGN……我大概是先被A吸引,慢慢接触C和N,现在更多是A和N。至于G……确实没有怎么接触 感觉是一大遗憾
虽然但是我这种人去看太刀的故事和太沉重的故事都不太好(
真的有人没时间开魔禁坑吗你只需要大概半年到一年的所有闲暇时间(
咳咳说得严重了点但魔禁确实是个大坑 我都没把握说我已经开全了
毕竟河马写得太快了 某巴西人不能学一下吗
虽然但是,高中前我似乎把很多精力放在了翻译上
这使得我玩(?)的时间就少了些
切题思路
一棵 \(n\) 个点的树,点有点权。\(q\) 次询问,每次给出两个点,询问两点间简单路径上点权异或最大值。
\(n \le 2e4,\ q \le 2e5,\ \text{size} \le 1e18\),时限3s。
一眼树剖,讨论单次询问。重剖可将一条简单路径拆成 \(O(\log n)\) 条重链,线段树上维护区间对应点权集合的线性基。单条重链在线段树上最多 \(O(\log n)\) 个区间,也就是 \(O(\log n)\) 个线性基合并,单次线段树上查询总复杂度 \(O(\log n \log^3 \text{size})\)。共 \(O(\log n)\) 条重链对应线性基进行合并,单次查询复杂度 \(O(\log^2 n \log^3 \text{size})\)。线段树建树时叶子节点插入单个点权,随后 \(\text{push_up()}\) 上提即可。预处理复杂度 \(O(n\log n \log^3 \text{size})\)。
如上分析可得此法总复杂度:\(O(n\log n \log^3 \text{size} + q\log^2 n \log^2 \text{size})\)。这不T飞天
评价:您完全不预处理是吗
观察可得,线段树查询部分可以被优化。在重链区间查询时,我们每次进行了 \(O(\log n)\) 次合并,而这是由于预处理不优秀导致的。我们完全可以通过ST表预处理的方式将合并 \(O(\log n)\) 次变成合并 \(O(1)\) 次。而这是易实现的。
^2
再次讨论单次询问。对于每条重链,在ST表上查询对应区间,进行单次线性基合并,总复杂度 \(O(\log^2 \text{size})\)。单次查询复杂度 \(O(\log n \log^2 \text{size})\)。ST表初始化时单个位置进行 \(O(\log^2 n)\) 次合并。预处理复杂度 \(O(n\log n \log^2 \text{size})\)。
此法总复杂度:\(O(n\log n \log^2 \text{size} + q\log n \log^2 \text{size})\)。可以通过。
虽然点分治会奇怪地很快,但是贪心的可拓展性似乎不是很广。srds贪心真的快相比之下还是树剖+ST表既好想又好写。思路1从成型到只剩T的点只用了一个小时多,而改ST表15min不到。
以及如果支持修改的话大概只能用思路1了。线段树单点修改两个 \(\log\),查询三个 \(\log\)。似乎没有什么好的带修 \(O(1)\) 或单 \(\log\) 的数据结构维护这玩意。大概是我见得太少了。
核心代码:
struct Linear_Basis {
ll a[62];
ll & operator [] (const int & pos) {
return a[pos];
}
ll operator [] (const int & pos) const {
return a[pos];
}
Linear_Basis operator + (Linear_Basis b) const {
rep(i, 0, bnd+1) b.insert(a[i]);
return b;
}
Linear_Basis operator += (const Linear_Basis & b) {
rep(i, 0, bnd+1) insert(b[i]);
return (*this);
}
void insert(ll t) {
pre(i, bnd+1, 0) {
if (t == 0) return;
if ((t & (1ll << i)) == 0) continue;
if (a[i]) t ^= a[i];
else {
rep(j,0,i-1) if ((t & (1ll << j))) t ^= a[j];
rep(j, i+1, bnd+1) if (a[j] & (1ll << i)) a[j] ^= t;
a[i] = t;
break;
}
}
}
ll qry() {
ll ret = 0;
rep(i, 0, bnd+1) ret ^= a[i];
return ret;
}
void init() { memset(a, 0, sizeof (a)); }
} Nil, st[N][20];
void init() {
rep(j,0,19) for (int i = 1; i + (1<<j) - 1 <= stp; i++) {
st[i][j+1] = st[i][j] + st[i + (1<<j)][j];
}
}
Linear_Basis st_qry(int l, int r) {
int d = __lg(r - l + 1);
return st[l][d] + st[r - (1<<d) + 1][d];
}
Linear_Basis qry(int u, int y) {
Linear_Basis ret = Nil;
while (top[u] != top[y]) {
if (dep[top[u]] < dep[top[y]]) swap(u, y);
ret += st_qry(dfn[top[u]], dfn[u]);
u = fa[top[u]];
} if (dep[u] > dep[y]) swap(u, y);
return ret + st_qry(dfn[u], dfn[y]);
}
以下是博客签名,与正文无关。
请按如下方式引用此页:
本文作者 joke3579,原文链接:https://www.cnblogs.com/joke3579/p/chitchat220726.html。
遵循 CC BY-NC-SA 4.0 协议。
请读者尽量不要在评论区发布与博客内文完全无关的评论,视情况可能删除。