[SCOI2016]幸运数字
很显然的暴力就是把路径上的数抽出来弄个线性基求答案
再优化一下就是用倍增的方式把数抽出来
倍增时涉及两个线性基合并,然后就是 了
竟没想到它可以过
#include <cstdio> #include <iostream> #define RE register #define IN inline using namespace std; typedef long long LL; const int N = 20005; int n, q, fa[N][16], h[N], tot, dep[N]; LL a[N]; struct edge{int to, nxt;}e[N << 1]; IN void add(int x, int y){e[++tot] = edge{y, h[x]}, h[x] = tot;} struct node{ LL p[61]; IN node(){for(RE int i = 0; i < 61; i++) p[i] = 0;} }f[N][16]; IN void Insert(node &a, LL x) { for(RE int i = 60; i >= 0; i--) if ((x >> i) & 1) { if (!a.p[i]){a.p[i] = x; return;} x ^= a.p[i]; } } IN void Merge(node &a, node b) { for(RE int i = 60; i >= 0; i--) if (b.p[i]) Insert(a, b.p[i]); } void dfs(int x, int dad) { for(RE int i = 1; i <= 15; i++) if (fa[x][i - 1]) fa[x][i] = fa[fa[x][i - 1]][i - 1], Merge(f[x][i], f[x][i - 1]), Merge(f[x][i], f[fa[x][i - 1]][i - 1]); else break; for(RE int i = h[x]; i; i = e[i].nxt) { int v = e[i].to; if (v == dad) continue; Insert(f[v][0], a[v]), fa[v][0] = x, dep[v] = dep[x] + 1; dfs(v, x); } } IN node Query(int u, int v) { node tmp; if (dep[u] < dep[v]) swap(u, v); int deep = dep[u] - dep[v]; for(RE int i = 15; i >= 0; i--) if ((deep >> i) & 1) Merge(tmp, f[u][i]), u = fa[u][i]; if (u == v){Insert(tmp, a[u]); return tmp;} for(RE int i = 15; i >= 0; i--) if (fa[u][i] ^ fa[v][i]) Merge(tmp, f[u][i]), Merge(tmp, f[v][i]), u = fa[u][i], v = fa[v][i]; Insert(tmp, a[u]), Insert(tmp, a[v]), Insert(tmp, a[fa[u][0]]); return tmp; } IN void read(int &x) { x = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()); for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar()); } IN void readLL(LL &x) { x = 0; char ch = getchar(); for(; !isdigit(ch); ch = getchar()); for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar()); } int main() { read(n), read(q); for(RE int i = 1; i <= n; i++) readLL(a[i]); for(RE int i = 1, u, v; i < n; i++) read(u), read(v), add(u, v), add(v, u); dfs(1, 0); node tmp; LL ans; for(RE int u, v; q; --q) { read(u), read(v), tmp = Query(u, v), ans = 0; for(RE int i = 60; i >= 0; i--) ans = max(ans, ans ^ tmp.p[i]); printf("%lld\n", ans); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)