题目传送门

幸运数字

题目描述

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

一些旅行者希望游览 A 国。旅行者计划乘飞机降落在 x 号城市,沿着 x 号城市到 y 号城市之间那条唯一的路径游览,最终从 y 城市起飞离开 A 国。在经过每一座城市时,游览者就会有机会与这座城市的幸运数字拍照,从而将这份幸运保存到自己身上。然而,幸运是不能简单叠加的,这一点游览者也十分清楚。他们迷信着幸运数字是以异或的方式保留在自己身上的。

例如,游览者拍了 3 张照片,幸运值分别是 5,7,11,那么最终保留在自己身上的幸运值就是 9(5 xor 7 xor 11)。

有些聪明的游览者发现,只要选择性地进行拍照,便能获得更大的幸运值。例如在上述三个幸运值中,只选择 5 和 11 ,可以保留的幸运值为 14 。现在,一些游览者找到了聪明的你,希望你帮他们计算出在他们的行程安排中可以保留的最大幸运值是多少。

输入输出格式

输入格式:

第一行包含 2 个正整数 n ,q,分别表示城市的数量和旅行者数量。

第二行包含 n 个非负整数,其中第 i 个整数 Gi 表示 i 号城市的幸运值。

随后 n-1 行,每行包含两个正整数 x ,y,表示 x 号城市和 y 号城市之间有一条道路相连。

随后 q 行,每行包含两个正整数 x ,y,表示这名旅行者的旅行计划是从 x 号城市到 y 号城市。N<=20000,Q<=200000,Gi<=2^60

输出格式:

输出需要包含 q 行,每行包含 1 个非负整数,表示这名旅行者可以保留的最大幸运值。

输入输出样例

输入样例#1:

4 2
11 5 7 9
1 2
1 3
1 4
2 3
1 4
输出样例#1:

14
11

  分析:

  树上线性基的模板。

  显然我们的做法应该是把树上路径的每个点构造成线性基然后求异或最大值。但问题在于我们如何快速构造出任意一条路径的线性基。

  这里采用倍增的思想。

  我们开一个三维数组$p[i][j][k]$表示从$i$跳$2^j$时路径上的线性基。在预处理倍增的时候,我们只要把两段$2^(j-1)$的线性基合并就能得到$2^j$的线性基。查询$lca$的时候用同样的方法就能得到一条路径上的线性基。

  代码略长,不太好看。

  Code:

//It is made by HolseLee on 13th Sep 2018
//Luogu.org P3292
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Max(a,b) (a)>(b)?(a):(b)
using namespace std; typedef long long ll;
const int N=2e4+;
int n,m,head[N],cnte,f[N][],dep[N];
ll p[N][][],ans[];
struct Edge{
int to,nxt;
Edge() {}
Edge(int _x,int _y): to(_x),nxt(_y) {}
}e[N<<]; inline ll read()
{
char ch=getchar(); ll num=; bool flag=false;
while( ch<'' || ch>'' ) {
if( ch=='-' ) flag=true; ch=getchar();
}
while( ch>='' && ch<='' ) {
num=num*+ch-''; ch=getchar();
}
return flag ? -num : num ;
} inline void add(int x,int y)
{
e[++cnte]=Edge(y,head[x]);
head[x]=cnte;
} void dfs(int u,int las)
{
f[u][]=las; dep[u]=dep[las]+;
for(int i=head[u]; i; i=e[i].nxt) {
if( e[i].to==las ) continue;
dfs(e[i].to,u);
}
} inline void liner(ll *x,ll y)
{
for(int i=; i>=; --i) {
if( (y>>i)& ) {
if( !x[i] ) {
x[i]=y; break;
} else {
y^=x[i];
}
}
}
} inline void merge(ll *x,ll *y)
{
for(int i=; i>=; --i) {
if( y[i] ) liner(x,y[i]);
}
} void ready()
{
for(int j=; j<=; ++j)
for(int i=; i<=n; ++i) {
f[i][j]=f[f[i][j-]][j-];
memcpy(p[i][j],p[i][j-],sizeof(p[i][j-]));
merge(p[i][j],p[f[i][j-]][j-]);
}
} inline void lca(int x,int y)
{
if( dep[x]<dep[y] ) swap(x,y);
for(int i=; i>=; --i)
if( dep[f[x][i]]>=dep[y] )
merge(ans,p[x][i]), x=f[x][i];
if( x==y ) {
merge(ans,p[x][]); return;
}
for(int i=; i>=; --i)
if( f[x][i]!=f[y][i] ) {
merge(ans,p[x][i]), merge(ans,p[y][i]);
x=f[x][i], y=f[y][i];
}
merge(ans,p[x][]), merge(ans,p[y][]);
merge(ans,p[f[x][]][]);
} int main()
{
n=read(); m=read();
for(int i=; i<=n; ++i) {
liner(p[i][],read());
}
int x,y;
for(int i=; i<n; ++i) {
x=read(), y=read();
add(x,y); add(y,x);
}
dfs(,); ready();
ll ret;
for(int i=; i<=m; ++i) {
x=read(), y=read();
ret=;
memset(ans,,sizeof(ans));
lca(x,y);
for(int i=; i>=; --i) {
ret=Max(ret,ret^ans[i]);
}
printf("%lld\n",ret);
}
return ;
}

洛谷P3292 [SCOI2016] 幸运数字 [线性基,倍增]的更多相关文章

  1. 洛谷P3292 [SCOI2016]幸运数字 线性基+倍增

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

  2. P3292 [SCOI2016]幸运数字 [线性基+倍增]

    线性基+倍增 // by Isaunoya #include <bits/stdc++.h> using namespace std; #define rep(i, x, y) for ( ...

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

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

  4. P3292 [SCOI2016]幸运数字 线性基

    正解:线性基+倍增 解题报告: 先放下传送门QAQ 然后这题,其实没什么太大的技术含量,,,?就几个知识点套在一起,除了代码长以外没任何意义,主要因为想复习下线性基的题目所以还是写下,,, 随便写下思 ...

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

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

  6. 洛谷P3292 [SCOI2016]幸运数字(倍增+线性基)

    传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 第一眼:这不会是个倍增LCA暴力合并线性基吧…… 打了一发……A了? 所以这真的是个暴力倍增LCA合并线性基么…… ps:据某大佬说其实可以离线之后 ...

  7. BZOJ4568: [Scoi2016]幸运数字(线性基 倍增)

    题意 题目链接 Sol 线性基是可以合并的 倍增维护一下 然后就做完了?? 喵喵喵? // luogu-judger-enable-o2 #include<bits/stdc++.h> # ...

  8. BZOJ 4568 [Scoi2016]幸运数字 ——线性基 倍增

    [题目分析] 考虑异或的最大值,维护线性基就可以了. 但是有多次的询问,树剖或者倍增都可以. 想了想树剖动辄数百行的代码. 算了,我还是写倍增吧. 注:被位运算和大于号的优先级坑了一次,QaQ [代码 ...

  9. bzoj4568 [Scoi2016]幸运数字 线性基+树链剖分

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

随机推荐

  1. package.json文档

    之前在博客中写过一篇关于 " node.js的安装配置 " 的文章,里面有提到利用 gulp watch 来监听文档的变化.其中需要 package.json 文件才能实现效果,所 ...

  2. zoj 3229 Shoot the Bullet(有源汇上下界最大流)

    Shoot the Bullethttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3442 Time Limit: 2 Second ...

  3. HDU 1431 思维 基础数论

    找范围内回文素数,最大到1e8,我就是要枚举回文串,再判素数,然后因为这种弱智思路死磕了很久题目. /** @Date : 2017-09-08 15:24:43 * @FileName: HDU 1 ...

  4. Uva5211/POJ1873 The Fortified Forest 凸包

    LINK 题意:给出点集,每个点有个价值v和长度l,问把其中几个点取掉,用这几个点的长度能把剩下的点围住,要求剩下的点价值和最大,拿掉的点最少且剩余长度最长. 思路:1999WF中的水题.考虑到其点的 ...

  5. Bayesian optimisation for smart hyperparameter search

    Bayesian optimisation for smart hyperparameter search Fitting a single classifier does not take long ...

  6. web开发之Servlet 二

    在上一篇文章中,我们演示也证明了Servlet 是一种动态web资源开发的技术,即我可以在浏览器中输入URL,然后就可以在浏览器中看到我们编写的Servlet资源. 那当我们在浏览器上一起一个HTTP ...

  7. [译]Quartz 框架 教程(中文版)2.2.x 之第二课 Quartz API,Jobs和Triggers简介

    第二课:QuartzAPI,Jobs和Triggers简介 Quartz API Quartz API 关键的几个接口: Scheduler:跟任务调度相关的最主要的API接口. Job:你期望任务调 ...

  8. iOS 程序启动流程

    iOS程序启动原理   技术博客http://www.cnblogs.com/ChenYilong/ 新浪微博http://weibo.com/luohanchenyilong   iOS应用程序运行 ...

  9. MongoDB中的基础概念:Databases、Collections、Documents

    MongoDB以BSON格式的文档(Documents)形式存储.Databases中包含集合(Collections),集合(Collections)中存储文档(Documents). BSON是一 ...

  10. JS设计模式——2.初识接口

    什么是接口 接口提供了一种用以说明一个对象应该具有哪些方法的手段. 接口之利 1.接口具有自我描述性从而促进代码的重用 2.接口有助于稳定不同中的类之间的通信方式 3.测试和调试也变得更轻松 接口之弊 ...