题目


分析

题目就是将\(x\)到\(y\)路径上的线性基合并求解,

这里用的是点分治,每次换根到重心的时候维护前缀线性基,

查询的时候如果属于不同的子树就能询问答案,记得\(x=y\)要特判


代码

#include <cstdio>
#include <cctype>
#include <cstring>
#define rr register
using namespace std;
typedef long long lll; const int N=20011,M=200011;
struct node{int y,next;}e[N<<1],E[M<<1];
int n,siz[N],big[N],as[N],SIZ,et=1,Et=1,tot,Q;
int v[N],root,b[N],is_ed[M],hs[N],st[N]; long long a[N],ans[M];
inline lll iut(){
rr lll ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(lll ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Vector_Space{
lll re[61];
inline void BUILD(){
memset(re,0,sizeof(re));
}
inline void Insert(lll x){
for (rr int i=60;~i;--i)
if ((x>>i)&1){
if (!re[i]) {re[i]=x; return;}
x^=re[i];
}
}
inline lll query(lll x){
for (rr int i=60;~i;--i)
if ((x^re[i])>x) x^=re[i];
return x;
}
}H[N];
inline Vector_Space comb(Vector_Space A,Vector_Space B){
rr Vector_Space C; C=A;
for (rr int i=60;~i;--i) C.Insert(B.re[i]);
return C;
}
inline signed max(int a,int b){return a>b?a:b;}
inline void dfs(int x,int fa){
siz[x]=1,big[x]=0;
for (rr int i=as[x];i;i=e[i].next)
if (e[i].y!=fa&&!v[e[i].y]){
dfs(e[i].y,x);
siz[x]+=siz[e[i].y];
big[x]=max(big[x],siz[e[i].y]);
}
big[x]=max(big[x],SIZ-siz[x]);
if (big[x]<big[root]) root=x;
}
inline void Get(int x,int fa,int bel){
st[++tot]=x,b[x]=bel,H[x]=H[fa],H[x].Insert(a[x]);
for (rr int i=as[x];i;i=e[i].next)
if (!v[e[i].y]&&e[i].y!=fa) Get(e[i].y,x,bel);
}
inline void calc(int x){
st[tot=1]=b[x]=x,H[x].BUILD(),H[x].Insert(a[x]);
for (rr int i=as[x];i;i=e[i].next)
if (!v[e[i].y]) Get(e[i].y,x,e[i].y);
for (rr int i=1;i<=tot;++i)
for (rr int j=hs[st[i]];j;j=E[j].next)
if (!is_ed[j>>1]&&(b[st[i]]^b[E[j].y]))
is_ed[j>>1]=1,ans[j>>1]=comb(H[st[i]],H[E[j].y]).query(0);
}
inline void dp(int x){
v[x]=1,calc(x);
for (rr int i=as[x];i;i=e[i].next)
if (!v[e[i].y]){
big[0]=SIZ=siz[e[i].y];
dfs(e[i].y,root=0),dp(root);
}
}
signed main(){
n=iut(),Q=iut();
for (rr int i=1;i<=n;++i) a[i]=iut();
for (rr int i=1;i<n;++i){
rr int x=iut(),y=iut();
e[++et]=(node){y,as[x]},as[x]=et;
e[++et]=(node){x,as[y]},as[y]=et;
}
for (rr int i=1;i<=Q;++i){
rr int x=iut(),y=iut();
if (x==y) ans[i]=a[x],is_ed[i]=1;
E[++Et]=(node){y,hs[x]},hs[x]=Et;
E[++Et]=(node){x,hs[y]},hs[y]=Et;
}
big[0]=SIZ=n,dfs(1,root=0),dp(root);
for (rr int i=1;i<=Q;++i)
print(ans[i]),putchar(10);
return 0;
}

#线性基,点分治#洛谷 3292 [SCOI2016]幸运数字的更多相关文章

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

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

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

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

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

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

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

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

  5. Luogu 3292 [SCOI2016]幸运数字

    BZOJ 4568. 感觉很板. 前置技能:线性基.      放一篇感觉讲的比较丰富的博客: 戳这里. 首先要求在一个序列中任意选点使得异或和最大,当然是想到线性基了. 把问题转换到树上,如果每次询 ...

  6. [洛谷P2567] SCOI2010 幸运数字

    问题描述 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是&quo ...

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

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

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

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

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

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

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

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

随机推荐

  1. 时序数据库timescaleDB安装

    一:前言相关 环境:Red Hat 8.3.1-5安装程序:PostgreSQL 14.1,TimescaleDB 2.5.1,cmake3.22.1PostgreSQL编译安装需要cmake3.4以 ...

  2. 记一个 Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 编译问题引发的案例

    某天将项目 kotlin 版本升级到了 1.8.0 ,然后编译报错了, Duplicate class kotlin-stblib vs kotlin-stdlib-jdk7/8 然后开始寻求解决方案 ...

  3. Flask学习(三)

    数据库操作 数据库驱动(drivers)模块:pymysql.MySQLDB ORM ORM 全拼Object-Relation Mapping,中文意为 对象-关系映射.主要实现模型对象到关系数据库 ...

  4. 【LeetCode二叉树#07】左叶子节点之和(基于栈的迭代法前中后序遍历复习)

    左叶子节点之和 力扣题目链接(opens new window) 计算给定二叉树的所有左叶子之和. 示例: 思路 注意审题,这里是要求 左叶子节点 之和 不是二叉树中的左侧节点之和,因此使用层序遍历是 ...

  5. 微信小程序:接手项目,修bug

    好家伙,   问题描述如下: 小程序主界面,选择快速上传会议记录 选择快速 其中,没有2022-2023第二学期,所以,新的会议记录无法上传 于是,我自愿修复这个bug 由于我们没有产品文档 我只能由 ...

  6. 【Application Insights】使用CURL命令向Application Insgihts发送测试数据

    问题描述 在使用App Service或者Kubernetes等服务时,需要收集一些日志数据并且发送到Application Insights中,当使用SDK或者是服务自带的Application I ...

  7. Java ----多线程 案例

    1 package bytezero.threadtest2; 2 3 /** 4 * 银行有一个账户 5 * 有两个储户分别向同一个账户存 3000元,每次存1000,存三次,每次存完打印账户余额 ...

  8. Java 小练习(2) 利用面向对象的编程方法 设计类Circle计算圆的面积

    1 package com.bytezero.exer; 2 /*** 3 * 4 * @Description 5 * @author Bytezero·zhenglei! Email:420498 ...

  9. 并发编程 --- CAS原子操作

    介绍 CAS(Compare And Swap) 是一种无锁算法的实现手段,中文名称为比较并交换.它由 CPU 的原子指令实现,可以在多线程环境下实现无锁的数据结构. 原理 CAS 的原理是:它会先比 ...

  10. 【技术积累】Java 8 新特性

    一.Lambda表达式 Lambda 是一个匿名函数,我们可以把 Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风格,使J ...