BZOJ 4568。

感觉很板。

前置技能:线性基。      放一篇感觉讲的比较丰富的博客: 戳这里

首先要求在一个序列中任意选点使得异或和最大,当然是想到线性基了。

把问题转换到树上,如果每次询问的序列是两点之间的路径,也就是说我们只要提取出树上一条路径的线性基就可以了吧。

发现线性基满足可以快速合并这个性质,如果要合并的话只要把一个暴力插到另一个里面去就行了,这样是两个$log$,我们还可以启发式合并,把小的插到大的里面去,这样会更快。

所以我们发现可以链剖或者倍增来维护这个东西,我这么懒,当然是倍增了。

注意倍增的时候是点形成的集合而不是边形成的集合。

再提两句:

  1、线性基并不满足区间可减性,所以大力可持久化应该是不行的。

  2、点分治可以减少一个$log$,再用$tarjan$求一求$lca$会更快。

时间复杂度$O(nlog^3n)$。

Code:

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll; const int N = ;
const int B = ;
const int Lg = ; int n, qn, tot = , head[N], dep[N], fa[N][Lg];
ll a[N]; struct Edge {
int to, nxt;
} e[N << ]; inline void add(int from, int to) {
e[++tot].to = to;
e[tot].nxt = head[from];
head[from] = tot;
} template <typename T>
inline void read(T &X) {
X = ; char ch = ; T op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} struct Lp {
ll p[B]; int cnt; inline void init() {
cnt = ;
memset(p, 0LL, sizeof(p));
} inline void ins(ll val) {
for(int i = ; i >= ; i--) {
if((val >> i) & ) {
if(!p[i]) {
p[i] = val;
++cnt;
break;
}
val ^= p[i];
}
}
} inline ll getMax() {
ll res = 0LL;
for(int i = ; i >= ; i--)
if((res ^ p[i]) > res) res ^= p[i];
return res;
} } s[N][Lg]; inline Lp merge(Lp u, Lp v) {
Lp res; res.init();
if(u.cnt > v.cnt) {
res = u;
for(int i = ; i >= ; i--) {
if(!v.p[i]) continue;
res.ins(v.p[i]);
}
} else {
res = v;
for(int i = ; i >= ; i--) {
if(!u.p[i]) continue;
res.ins(u.p[i]);
}
}
return res;
} inline void swap(int &x, int &y) {
int t = x; x = y; y = t;
} void dfs(int x, int fat, int depth) {
fa[x][] = fat, dep[x] = depth;
s[x][].init();
if(fat) s[x][].ins(a[fat]);
for(int i = ; i <= ; i++) {
fa[x][i] = fa[fa[x][i - ]][i - ];
s[x][i] = merge(s[x][i - ], s[fa[x][i - ]][i - ]);
}
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(y == fat) continue;
dfs(y, x, depth + );
}
} inline Lp getLp(int x, int y) {
Lp res; res.init();
res.ins(a[x]), res.ins(a[y]);
if(dep[x] < dep[y]) swap(x, y);
for(int i = ; i >= ; i--)
if(dep[fa[x][i]] >= dep[y]) {
res = merge(res, s[x][i]);
x = fa[x][i];
}
if(x == y) return res;
for(int i = ; i >= ; i--)
if(fa[x][i] != fa[y][i]) {
res = merge(res, s[x][i]), res = merge(res, s[y][i]);
x = fa[x][i], y = fa[y][i];
}
res = merge(res, s[x][]), res = merge(res, s[y][]);
return res;
} inline void solve(int x, int y) {
Lp res = getLp(x, y);
printf("%lld\n", res.getMax());
} int main() {
read(n), read(qn);
for(int i = ; i <= n; i++) read(a[i]);
for(int x, y, i = ; i < n; i++) {
read(x), read(y);
add(x, y), add(y, x);
} dfs(, , ); for(int x, y; qn--; ) {
read(x), read(y);
solve(x, y);
} return ;
}

唔,Linear Basis居然被我写成了Lp……无话可说

Luogu 3292 [SCOI2016]幸运数字的更多相关文章

  1. BZOJ 4568: [Scoi2016]幸运数字 [线性基 倍增]

    4568: [Scoi2016]幸运数字 题意:一颗带点权的树,求树上两点间异或值最大子集的异或值 显然要用线性基 可以用倍增的思想,维护每个点向上\(2^j\)个祖先这些点的线性基,求lca的时候合 ...

  2. [SCOI2016]幸运数字 树链剖分,线性基

    [SCOI2016]幸运数字 LG传送门 为了快乐,我们用树剖写这题. 强行树剖,线段树上每个结点维护一个线性基,每次查询暴力合并. 瞎分析一波复杂度:树剖两点之间\(\log n\)条重链,每条重链 ...

  3. bzoj 4568: [Scoi2016]幸运数字

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 848  Solved: 336[Submit][Status ...

  4. [洛谷P3292] [SCOI2016]幸运数字

    洛谷题目链接:[SCOI2016]幸运数字 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城 ...

  5. 【BZOJ 4568】 4568: [Scoi2016]幸运数字 (线性基+树链剖分+线段树)

    4568: [Scoi2016]幸运数字 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形 ...

  6. [BZOJ4568][Scoi2016]幸运数字 倍增+线性基

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1791  Solved: 685[Submit][Statu ...

  7. [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)

    4568: [Scoi2016]幸运数字 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2131  Solved: 865[Submit][Statu ...

  8. 【BZOJ4568】[Scoi2016]幸运数字 倍增+线性基

    [BZOJ4568][Scoi2016]幸运数字 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念 ...

  9. bzoj4568: [Scoi2016]幸运数字(LCA+线性基)

    4568: [Scoi2016]幸运数字 题目:传送门 题解: 好题!!! 之前就看过,当时说是要用线性基...就没学 填坑填坑: %%%线性基 && 神犇 主要还是对于线性基的运用和 ...

随机推荐

  1. DedeCMS织梦模板标签调用大全

    本文转载:http://www.mubanzhijia.com/jishujiaocheng/1.html 关键描述调用标签: <meta name="keywords" c ...

  2. CodeForces - 896D :Nephren Runs a Cinema(卡特兰数&组合数学---比较综合的一道题)

    Lakhesh loves to make movies, so Nephren helps her run a cinema. We may call it No. 68 Cinema. Howev ...

  3. burpsuite使用以及repeater模块实现重放攻击

    第一.burp suit是什么? Burp Suite 包含了一系列burp 工具,这些工具之间有大量接口可以互相通信,之所以这样设计的目的是为了促进和提高 整个攻击的效率.平台中所有工具共享同一ro ...

  4. Linux命令学习(22):ss命令

    版权声明 更新:2017-05-20 博主:LuckyAlan 联系:liuwenvip163@163.com 声明:吃水不忘挖井人,转载请注明出处! 1 文章介绍 本文介绍了Linux下面的ss命令 ...

  5. Brackets (区间DP)

    个人心得:今天就做了这些区间DP,这一题开始想用最长子序列那些套路的,后面发现不满足无后效性的问题,即(,)的配对 对结果有一定的影响,后面想着就用上一题的思想就慢慢的从小一步一步递增,后面想着越来越 ...

  6. [Unity3D]关于U3D贴图格式压缩

    http://blog.sina.com.cn/s/blog_5b6cb9500102vi6i.html 因为有不少人都问过我压缩格式的问题,今天飞哥又重新提醒了一次.整理一下发个贴,以供大家查阅和讨 ...

  7. [转]JavaScript之数据类型

    数据类型 JavaScript中有5种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number和String.还有1种复杂数据类型——Object,Object本 ...

  8. BZOJ1047:[HAOI2007]理想的正方形

    浅谈队列:https://www.cnblogs.com/AKMer/p/10314965.html 题目传送门:https://lydsy.com/JudgeOnline/problem.php?i ...

  9. Python:函数变量的使用

    1.上层函数不能直接使用其嵌套函数的变量: def func1(x, y): z = x + y def func2(): m = 3 z += m return z print(func1(1, 2 ...

  10. Disconf web管理端安装

    1.环境配置配置java.maven环境,并安装mysql,reids,zookeeeper,Nginx2.下载disconf下载https://codeload.github.com/knightl ...