题目链接

loj#2013. 「SCOI2016」幸运数字

题解

和树上路径有管...点分治吧

把询问挂到点上

求出重心后,求出重心到每个点路径上的数的线性基

对于重心为lca的合并寻味,否则标记下传

对于每个询问,只需要暴力合并两个线性基即可

每个点只会被加到logn个线性基里,所以总复杂度为O(nlogn60 + q60*2)

然后我写了句memset(b,0,sizeof 0)...被卡了1h...

代码

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm> inline int read() {
int x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
} inline long long Read() {
long long x = 0,f = 1;
char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar();
return x * f;
}
#define LL long long
const int maxn = 200007;
int n,m;
long long val[maxn];
struct node {
int v,next;
} edge[maxn << 1];
int head[maxn],num = 0;
inline void add_edge(int u,int v) {
edge[++ num].v = v;edge[num].next = head[u],head[u] = num;
} struct Base {
LL b[63];
inline void clear() {memset(b,0,sizeof b); }
inline void insert(LL x) {
for(int i = 60;~i;-- i)
if(x >> i & 1)
if(b[i]) x ^= b[i];
else {b[i] = x; break;}
}
inline void merge(const Base &x) {
for(int i = 60;~i;-- i)
if(x.b[i]) insert(x.b[i]);
}
inline LL query() {
LL ret = 0;
for(int i = 60;~i;-- i)
ret = std::max(ret ^ b[i],ret);
return ret;
}
} base[maxn]; int U[maxn],V[maxn],sz[maxn],bel[maxn];
LL ans[maxn];
std::vector<int>q[maxn];
bool vis[maxn]; int root = 0,mt;
void get_root(int x,int fa,int tot) {
sz[x] = 1; int mx = 0;
for(int i = head[x];i;i = edge[i].next) {
int v = edge[i].v;
if(v == fa || vis[v]) continue;
get_root(v,x,tot);
sz[x] += sz[v];
mx = std::max(mx,sz[v]);
}
mx = std::max(tot - sz[x],mx);
if(mx < mt) root = x, mt = mx;
}
void dfs(int x,int fa,int Bel) {
bel[x] = Bel; base[x] = base[fa]; base[x].insert(val[x]);
for(int i = head[x];i;i = edge[i].next)
if(edge[i].v != fa && !vis[edge[i].v])
dfs(edge[i].v,x,Bel);
}
int tq[maxn];
void solve(int x) {
if(!q[x].size()) return;
mt = 20005; get_root(x,x,sz[x]);
vis[root] = 1;
bel[root] = root;
base[root].clear();
base[root].insert(val[root]);
for(int i = head[root];i;i = edge[i].next)
if(!vis[edge[i].v])
dfs(edge[i].v,root,edge[i].v);
int tot = q[x].size();
for(int i = 0;i <= tot;++ i) tq[i] = q[x][i];
q[x].clear();
Base tmp;
for(int i = 0,id;i < tot;++ i) {
if(bel[U[id = tq[i]]] == bel[V[id]])
q[bel[U[id]]].push_back(id);
else
tmp = base[U[id]],
tmp.merge(base[V[id]]),
ans[id] = tmp.query();
}
for(int i = head[root];i;i = edge[i].next)
if(!vis[edge[i].v]) solve(edge[i].v);
}
int main() {
//freopen("lucky1.in","r",stdin);
n = read();m = read();
for(int i = 1;i <= n;++ i) val[i] = Read();
for(int u,v,i = 1;i < n;++ i) {
u = read(),v = read();
add_edge(u,v); add_edge(v,u);
}
for(int i = 1;i <= m;++ i) {
U[i] = read(),V[i] = read();
if(U[i] == V[i]) ans[i] = val[U[i]];
else q[1].push_back(i);
}
sz[1] = n; solve(1);
for(int i = 1;i <= m;++ i)
printf("%lld\n",ans[i]);
return 0;
}

loj#2013. 「SCOI2016」幸运数字 点分治/线性基的更多相关文章

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

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

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

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

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

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

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

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

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

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

  6. LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset

    题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...

  7. loj2013 「SCOI2016」幸运数字

    点分治+线性基 (为了这六个字窝调了一下午一晚上QAQ #include <iostream> #include <cstring> #include <cstdio&g ...

  8. luogu3292 幸运数字 (点分治+线性基)

    首先第一眼是一个倍增套线性基,但是$O(Qlog^2Vlog^N)=10^{10}$的复杂度... 即使是st表也只是变成了$O(Nlog^2Vlog^N)$啊 考虑点分治,相对于倍增显著减少了线性基 ...

  9. loj#2015. 「SCOI2016」妖怪 凸函数/三分

    题目链接 loj#2015. 「SCOI2016」妖怪 题解 对于每一项展开 的到\(atk+\frac{dnf}{b}a + dnf + \frac{atk}{a} b\) 令$T = \frac{ ...

随机推荐

  1. Xtion pro live OpenNI2.2 Nite 2.2 安装配置1.0

    1. 安装ubuntu14.04依赖项 $ sudo ln -s /lib/x86_64-linux-gnu/libudev.so.1.3.5 /lib/x86_64-linux-gnu/libude ...

  2. Check Box、Radio Button、Combo Box控件使用

    Check Box.Radio Button.Combo Box控件使用 使用控件的方法 1.拖动控件到对话框 2. 定义控件对应的变量(值变量或者控件变量) 3.响应控件各种消息 Check Box ...

  3. 【Python】多线程-线程池使用

    1.学习目标 线程池使用 2.编程思路 2.1 代码原理 线程池是预先创建线程的一种技术.线程池在还没有任务到来之前,创建一定数量的线程,放入空闲队列中.这些线程都是处于睡眠状态,即均为启动,不消耗 ...

  4. 【bzoj1901】dynamic ranking(带修改主席树/树套树)

    题面地址(权限题) 不用权限题的地址 首先说说怎么搞带修改主席树? 回忆一般的kth问题,我们的主席树求的是前缀和,这样我们在目标区间的左右端点的主席树差分下就能求出kth. 那么我们如何支持修改操作 ...

  5. centos6.5环境openldap实战之ldap配置详解及web管理工具lam(ldap-account-manager)使用详解

    ldap常用名称解释 1.环境搭建 操作系统:centos6.5 x86_64 关闭防火墙.selinux 开启时间同步 # crontab -e 加入 # time sync */5 * * * * ...

  6. Git学习笔记一《版本控制之道-使用Git》

    1.在Windows中安装完git后,需要进行一下配置:$ git config --global user.name "zhangliang"$ git config --glo ...

  7. Ex 3_17 无穷路径..._十一次作业

    (a) Inf(p)在p中出现了无穷多次,说明Inf(p)存在一个环当中,所以这个环的顶点肯定是某一个强连通部件的子集. (b) 若G中存在一条无穷路径,则G中至少存在一个环,且这个环至少有两个顶点, ...

  8. Expm 4_2 有向无环图中的最短路径问题

    [问题描述] 建立一个从源点S到终点E的有向无环图,设计一个动态规划算法求出从S到E的最短路径值,并输出相应的最短路径. 解: package org.xiu68.exp.exp4; import j ...

  9. 蝉知CMS本地迁移到服务器具体步骤

    蝉知迁移步骤(2个方案,二选一即可) 方案一(整个chanzhi(eps)目录拷贝,假设新安装的蝉知文件夹名称为chanzhieps): 1.在新服务器上安装相同版本(版本号必须一致)的蝉知(安装文档 ...

  10. Python-ccs动画及阴影

    动画及阴影 0. 什么时候该用什么布局 <!-- 定位布局: 以下两种布局不易解决的问题, 盒子需要脱离文档流处理 --> <!-- 浮动布局: 一般有block特性的盒子,水平排列 ...