点分治+线性基

(为了这六个字窝调了一下午一晚上QAQ

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cassert>
using namespace std;
typedef long long ll;
int n, uu, vv, m, hea[20005], cnt, sze, rot, rnd[20005], siz[20005], bel[20005];
bool vis[20005];
ll a[20005], ans[200005];
struct Edge{
int too, nxt;
}edge[40005];
struct Ques{
int u, v, idx;
};
struct LinearBase{
ll num[65];
void clear(){
memset(num, 0, sizeof(num));
}
void insert(ll x){
for(int i=60; i>=0; i--)
if(x&(1ll<<i)){
if(num[i]) x ^= num[i];
else{
num[i] = x;
break;
}
}
}
ll operator+(const LinearBase &x)const{
LinearBase c=x;
for(int i=60; i>=0; i--)
c.insert(num[i]);
ll re=0;
for(int i=60; i>=0; i--)
if((re^c.num[i])>re)
re ^= c.num[i];
return re;
}
}bas[20005];
vector<Ques> q[20005];
void add_edge(int fro, int too){
edge[++cnt].nxt = hea[fro];
edge[cnt].too = too;
hea[fro] = cnt;
}
void getRoot(int x, int f){
siz[x] = 1;
rnd[x] = 0;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f && !vis[t]){
getRoot(t, x);
siz[x] += siz[t];
rnd[x] = max(rnd[x], siz[t]);
}
}
rnd[x] = max(rnd[x], sze-siz[x]);
if(rnd[x]<rnd[rot]) rot = x;
}
void dfs1(int x, int f){
bas[x].insert(a[x]);
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f && !vis[t]){
bas[t] = bas[x];
dfs1(t, x);
}
}
}
void dfs2(int x, int f, int fro){
bel[x] = fro;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(t!=f && !vis[t]) dfs2(t, x, fro);
}
}
void work(int x){
vis[x] = true;
bas[x].clear();
dfs1(x, 0);
bel[x] = x;
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t]) dfs2(t, x, t);
}
for(int i=0; i<q[x].size(); i++)
if(q[x][i].u==x || q[x][i].v==x || bel[q[x][i].u]!=bel[q[x][i].v])
ans[q[x][i].idx] = bas[q[x][i].u] + bas[q[x][i].v];
else
q[bel[q[x][i].u]].push_back(q[x][i]);
q[x].clear();
for(int i=hea[x]; i; i=edge[i].nxt){
int t=edge[i].too;
if(!vis[t]){
rot = 0;
sze = siz[t];
getRoot(t, 0);
q[rot] = q[t];
if(rot!=t) q[t].clear();
work(rot);
}
}
}
int main(){
cin>>n>>m;
for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
for(int i=1; i<n; i++){
scanf("%d %d", &uu, &vv);
add_edge(uu, vv);
add_edge(vv, uu);
}
sze = n;
rnd[0] = 0x3f3f3f3f;
getRoot(1, 0);
for(int i=1; i<=m; i++){
scanf("%d %d", &uu, &vv);
if(uu==vv) ans[i] = a[uu];
else q[rot].push_back((Ques){uu, vv, i});
}
work(rot);
for(int i=1; i<=m; i++)
printf("%lld\n", ans[i]);
return 0;
}

loj2013 「SCOI2016」幸运数字的更多相关文章

  1. loj#2013. 「SCOI2016」幸运数字 点分治/线性基

    题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...

  2. AC日记——「SCOI2016」幸运数字 LiBreOJ 2013

    「SCOI2016」幸运数字 思路: 线性基: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20005 # ...

  3. loj #2013. 「SCOI2016」幸运数字

    #2013. 「SCOI2016」幸运数字 题目描述 A 国共有 n nn 座城市,这些城市由 n−1 n - 1n−1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以 ...

  4. 「洛谷3292」「BZOJ4568」「SCOI2016」幸运数字【倍增LCA+线性基+合并】

    [bzoj数据下载地址]不要谢我 先讲一下窝是怎么错的... \(MLE\)是因为数组开小了.. 看到异或和最大,那么就会想到用线性基. 如果不会线性基的可以参考一下我的学习笔记:「线性基」学习笔记a ...

  5. LOJ #2013「SCOI2016」幸运数字

    时限为什么这么大啊 明摆着放多$ log$的做法过啊$QAQ$ LOJ #2013 题意 有$ Q$次询问,每次询问树上一条链,点有点权,你需要选择一些链上的点使得异或和尽量大 点数$ \leq 2* ...

  6. 【LOJ】 #2013. 「SCOI2016」幸运数字

    题解 最大异或和,明显是个线性基 然而还有那么多路径--那就树分治,反正点数看起来很少,就是为了让人乘上一个60的常数嘛 把一个树的点分树记录下来,然后看看询问的两个点彼此相同的最后一个父亲是谁,把这 ...

  7. 「SCOI2010」幸运数字

    传送门 Luogu 解题思路 首先构造出所有的幸运数字. 然后考虑一个幸运数字会产生多少贡献. 对于一个数 \(x\),它在区间 \([l,r]\) 内的倍数的个数为 \(\lfloor \frac{ ...

  8. 「SCOI2016」围棋 解题报告

    「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ...

  9. 「SCOI2016」妖怪 解题报告

    「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ...

随机推荐

  1. 在Unity3d中解析Lua脚本的方法

    由于近期项目中提出了热更新的需求,因此本周末在Lua的陪伴下度过.对Lua与Unity3d的搭配使用,仅仅达到了一个初窥门径的程度,记录一二于此.水平有限,欢迎批评指正. 网络上关于Lua脚本和Uni ...

  2. SpringBoot热部署的两种方式

    SpringBoot热部署方式一共有两种,分别使用两种不同的依赖 SpringBoot 1.3后才拥有SpringBoot devtools热部署 ①:spring-boot-devtools   ② ...

  3. mkcert本地 HTTPS 加密证书生成工具

    软件介绍: mkcert 是一个生成本地 HTTPS 加密证书的工具,一个命令就可以生成证书,不需要任何配置. 下载地址: https://github.com/FiloSottile/mkcert/ ...

  4. MySQL++简单使用记录.md

    #1.简介 MySQL++ is a powerful C++ wrapper for MySQL’s C API. Its purpose is to make working with queri ...

  5. javaSe-String/StringBuffer

    //String字符串.在进行字符串拼接的时候总是改变栈中指向堆中的位置 //StringBuffer字符串.在进行字符串拼接的时候不改变栈中指向堆中的位置 package com.java.chap ...

  6. ASP.NET WebForm & MongoDB

    ASP.NET WebForm & MongoDB 最近在朋友介绍下,也跟着看AngularJS 买了一本三合一的书,Node.JS+MongoDB+AngularJS http://www. ...

  7. Android(java)学习笔记137:ListView编写步骤(重点)

    1.ListView在我们的手机android编写程序中使用是十分广泛的,比如如下图中 短信 和 手机设置 都是ListView的效果: 手机设置:             短信:    2.正因为这 ...

  8. 用户输入和while循环

    函数input()的工作原理 message=input('Tell me something,and I will repeat it back to you:') print(message) 编 ...

  9. java基础—this关键字

    一.this关键字

  10. The expected type was 'System.Int64' but the actual value was null.”

    System.InvalidOperationException:“An exception occurred while reading a database value for property ...