点分治+线性基

(为了这六个字窝调了一下午一晚上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. ThreadLocal源码解析,内存泄露以及传递性

    我想ThreadLocal这东西,大家或多或少都了解过一点,我在接触ThreadLocal的时候,觉得这东西很神奇,在网上看了很多博客,也看了一些书,总觉得有一个坎跨不过去,所以对ThreadLoca ...

  2. css继承性

    不可继承的:display.margin.border.padding.background.height.min-height.max- height.width.min-width.max-wid ...

  3. If people in the communications only think about gains and losses of interest, then the pleasure of knowing each other will cease to exist.

    If people in the communications only think about gains and losses of interest, then the pleasure of ...

  4. hive中select中DISTINCT的技巧和使用

    hive中select中DISTINCT的技巧和使用 单表的唯一查询用:distinct 多表的唯一查询用:group by 在使用MySQL时,有时需要查询出某个字段不重复的记录,虽然mysql提供 ...

  5. SQL Server Sleeping会话占用内存资源浅析?

      在SQL Server中,会话的状态有运行(Running).睡眠(Sleeping).休眠(Dormant).Preconnect 等状态,有时候你会在数据库中看到很多会话处于睡眠(Sleepi ...

  6. 洛谷 P1079 Vigenère 密码

    题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南 ...

  7. Java和ABAP中的几种引用类型的分析和比较

    Java编程语言中几种不同的引用类型是面试时经常容易被问到的问题:强引用,软引用,弱引用,虚引用. 其实除了Java之外,某些 其他编程语言也有类似概念,比如ABAP.今天我们就来比较一下. 根据AB ...

  8. 人脸识别 python调用face++ 功能测试

    使用python调用face++的API,调用detect功能,识别人脸 首先进入face++官网注册,获得API Key和API Secret.使用官网提供的免费python api调用功能,提供了 ...

  9. codeforces Gym 100286J Javanese Cryptoanalysis (二染色)

    每一单词相邻两个字母,不能同时为元音或者辅音... 各种姿势都可以过:7个for,dp,黑白染色,dfs,并查集.... 最主要的思路就是相邻字母连边,把元音和辅音看成两个集合,那么有连边的两个字母一 ...

  10. 数据库-SQL语法:把一个字段的值设为随机整数

     update test2 set zuig = (cast ( ceiling (rand()*9) as int))