点分治+线性基

(为了这六个字窝调了一下午一晚上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;
}

最新文章

  1. Android 控件属性介绍
  2. JTree使用
  3. iOS中NSScanner 的用法
  4. OC之从键盘输入NSString字符串
  5. centos7虚拟机无法上网的解决办法
  6. linux集群时间同步
  7. 把mysql 中的字符gb2312 改为gbk的方法
  8. 【 D3.js 入门系列 --- 10.2 】 你可以拖动地图
  9. MySQL&nbsp;升级方法指南大全
  10. Go的变量作用域
  11. Redis的各项功能解决了哪些问题?
  12. MVC5+EF6 完整教程17--升级到EFCore2.0(转)
  13. Go基础系列:import导包和初始化阶段
  14. java使用代理请求https
  15. [No000011A]Office Excel设置显示日期与星期
  16. KB和KiB的区别
  17. Tomcat类加载器破坏双亲委派
  18. struts2从浅至深(六)总结
  19. check选择样式
  20. [golang note] 工程组织

热门文章

  1. GreenDao使用踩过的坑
  2. Hbase region查找过程
  3. session会话
  4. Ubuntu 配置IP地址方法
  5. PostgreSQL缓存
  6. POJ 2411 Mondriaan&#39;s Dream (状压DP,骨牌覆盖,经典)
  7. php 基本连接mysql数据库和查询数据
  8. LiteIDE 错误: 进程无法启动
  9. PHP RBAC权限控制,基于CI框架(版本3.1.9)
  10. 我如何解决Centos下cannot find a valid baseurl for repo的问题的