题目

给出一棵树,每个节点上有权值\(a_i\),多次询问一条路径上选择一些点权值异或和最大值。\(n\le 2\times 10^4,q\le 2\times 10^5,0\le a_i\le 2\times 2^{60}\)。

分析

选择一些点的异或和最大值显然用到线性基,这又是一个树上的路径问题,所以可以考虑倍增。预处理出倍增线性基,查询的时候倍增合并线性基,利用线性基的方法查询(从高往低能变大就异或)最大值。

这个总复杂度为\(O((n+q)\log n\log^2 a)\)。(线性基插入为\(\log a\),合并的时候有\(\log a\)个要插入)。

算起来是非常大的呢!但是可以过!

于是就开始寻找更好的做法

有两种更好的方法,参考上面zwl的博客。

首先由于线性基重复是不影响的,所以可以直接按 \(O(1)\) RMQ的方法来做,这样一共最多只需要合并4次线性基,所以就少掉一个log!

另一种做法是用点分治离线处理询问。对于每个重心求出到每个子树中节点的线性基,再给子树标号,判断当前重心上的询问是否通过重心。如果是的话就合并一次线性基得到答案,否则就把询问丢进所在的子树中。

这样总复杂度为\(O(n\log n\log a+q\log ^2a+q\log n)\),分别是点分构建线性基,总询问复杂度和每层扫描询问复杂度。

很奇妙呢!!

代码

于是我写的是开始的正常(不科学)方法。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long giant;
const int maxn=2e4+1;
const int maxj=15;
const int maxg=61;
int n,m,f[maxn][maxj],dep[maxn];
giant a[maxn];
struct base {
giant a[maxg];
inline void clear() {memset(a,0,sizeof a);}
base () {clear();}
void insert(giant x) {
for (int j=maxg-1;j>=0;--j) if ((x>>j)&1) {
if ((a[j]>>j)&1) x^=a[j]; else {
a[j]=x;
break;
}
}
}
giant mx() {
giant ret=0;
for (int j=maxg-1;j>=0;--j) if ((ret^a[j])>ret) ret^=a[j];
return ret;
}
} b[maxn][maxj];
base operator + (base a,base b) {
for (int j=maxg-1;j>=0;--j) if (b.a[j]) a.insert(b.a[j]);
return a;
}
vector<int> g[maxn];
inline void add(int x,int y) {g[x].push_back(y);}
void dfs(int x,int fa) {
f[x][0]=fa;
dep[x]=dep[fa]+1;
for (int v:g[x]) if (v!=fa) {
b[v][0].insert(a[x]);
dfs(v,x);
}
}
int lca(int x,int y) {
if (dep[x]<dep[y]) swap(x,y);
for (int j=maxj-1;j>=0;--j) if (dep[f[x][j]]>=dep[y]) x=f[x][j];
if (x==y) return x;
for (int j=maxj-1;j>=0;--j) if (f[x][j]!=f[y][j]) x=f[x][j],y=f[y][j];
return f[x][0];
}
base get(int x,int p) {
base ret;
ret.insert(a[x]);
for (int j=maxj-1;j>=0;--j) if (dep[f[x][j]]>=dep[p]) ret=ret+b[x][j],x=f[x][j];
return ret;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
#endif
scanf("%d%d",&n,&m);
for (int i=1;i<=n;++i) scanf("%lld",a+i);
for (int i=1;i<n;++i) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
dfs(1,1);
for (int j=1;j<maxj;++j) for (int i=1;i<=n;++i) {
f[i][j]=f[f[i][j-1]][j-1];
b[i][j]=b[i][j-1]+b[f[i][j-1]][j-1];
}
while (m--) {
int x,y;
scanf("%d%d",&x,&y);
if (x==y) {
printf("%lld\n",a[x]);
continue;
}
if (dep[x]>dep[y]) swap(x,y);
int l=lca(x,y);
base c=(x==l?get(y,l):get(x,l)+get(y,l));
giant ans=c.mx();
printf("%lld\n",ans);
}
return 0;
}

bzoj4568-幸运数字的更多相关文章

  1. 【bzoj4568 scoi2016】幸运数字

    题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征. 一些旅行者希望 ...

  2. 【BZOJ4568】幸运数字(线性基,树链剖分,ST表)

    [BZOJ4568]幸运数字(线性基,树链剖分,ST表) 题面 BZOJ Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市 ...

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

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

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

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

  5. 【BZOJ-4568】幸运数字 树链剖分 + 线性基合并

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

  6. BZOJ4568:[SCOI2016]幸运数字——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4568 https://www.luogu.org/problemnew/show/P3292 A ...

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

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

  8. 【线性基合并 树链剖分】bzoj4568: [Scoi2016]幸运数字

    板子题 Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市 ...

  9. 【bzoj4568】[Scoi2016]幸运数字 树上倍增+高斯消元动态维护线性基

    题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游 ...

  10. 【bzoj4568】【Scoi2016】幸运数字 (线性基+树上倍增)

    Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一 ...

随机推荐

  1. 使用装饰器@property

    1.在绑定属性时,如果我们直接把属性暴露出去,虽然写起来很简单,但是,没办法检查参数,导致可以把成绩随便改: s = Student() s.score = 98s.score = 1000 # 属性 ...

  2. 你不需要jQuery You Don't Need jQuery

    转载:https://github.com/oneuijs/You-Dont-Need-jQuery/blob/master/README.zh-CN.md You Don't Need jQuery ...

  3. [POJ3041]Asteroids

    Asteroids 好久没打过网络流相关的题了...... 题意:一个矩阵n×n,有m个东西,一次去掉一整行或一整列,问最少次数. 题解:匈牙利. 把每行变成一个点(X集合),每列变成一个点(Y集合) ...

  4. javaweb(二十四)——jsp传统标签开发

    一.标签技术的API 1.1.标签技术的API类继承关系 二.标签API简单介绍 2.1.JspTag接口 JspTag接口是所有自定义标签的父接口,它是JSP2.0中新定义的一个标记接口,没有任何属 ...

  5. _INTSIZEOF

    在_INTSIZEOF中该有的都有了 1.这其中最小非负剩余和最大正余数例子如下: 设n为4,当r为1时,最小非负剩余就是1,最大非正剩余就是1 - 4 = -3,最大正余数为4 - 1 = 3 2. ...

  6. Mac系统STF自动化环境搭建及部署踩坑记录

    因为公司需要寻找一个免root的自动化测试方案,所以以前做的老方案需要被替代.一阵搜寻找到了这个框架,但是部署起来很是折腾,搞了一下午终于搞定,顺便记录一下过程,有需要的自取. 转载请注明出处:htt ...

  7. CsvHelper文档-4映射

    CsvHelper文档-4映射 类映射 有时候你的类成员和csv的header不一定对应,有时候你的csv文件根本就没有header行,你需要特别制定一个成员的index,你不能依靠.net中默认的顺 ...

  8. C语言--指针详解

    这段时间在看 Linux 内核,深觉 C 语言功底不扎实,很多代码都看不太懂,深入学习巩固 C 语言的知识很有必要.先从指针开始. 一.什么是指针 C语言里,变量存放在内存中,而内存其实就是一组有序字 ...

  9. Linux 150命令之查看文件及内容处理命令 cat tac less head tail cut

    cat 查看文件内容 [root@mysql tmp]# cat 2.txt 1234 -n 查看行号 [root@mysql tmp]# cat -n 2.txt      1 1234       ...

  10. 2.airflow参数简介

    比较重要的参数: 参数 默认值 说明 airflow_home /home/airflow/airflow01 airflow home,由环境变量$AIRFLOW_HOME决定 dags_folde ...