loj2013 「SCOI2016」幸运数字
点分治+线性基
(为了这六个字窝调了一下午一晚上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」幸运数字的更多相关文章
- loj#2013. 「SCOI2016」幸运数字 点分治/线性基
		题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ... 
- AC日记——「SCOI2016」幸运数字 LiBreOJ 2013
		「SCOI2016」幸运数字 思路: 线性基: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 20005 # ... 
- loj #2013. 「SCOI2016」幸运数字
		#2013. 「SCOI2016」幸运数字 题目描述 A 国共有 n nn 座城市,这些城市由 n−1 n - 1n−1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以 ... 
- 「洛谷3292」「BZOJ4568」「SCOI2016」幸运数字【倍增LCA+线性基+合并】
		[bzoj数据下载地址]不要谢我 先讲一下窝是怎么错的... \(MLE\)是因为数组开小了.. 看到异或和最大,那么就会想到用线性基. 如果不会线性基的可以参考一下我的学习笔记:「线性基」学习笔记a ... 
- LOJ #2013「SCOI2016」幸运数字
		时限为什么这么大啊 明摆着放多$ log$的做法过啊$QAQ$ LOJ #2013 题意 有$ Q$次询问,每次询问树上一条链,点有点权,你需要选择一些链上的点使得异或和尽量大 点数$ \leq 2* ... 
- 【LOJ】 #2013. 「SCOI2016」幸运数字
		题解 最大异或和,明显是个线性基 然而还有那么多路径--那就树分治,反正点数看起来很少,就是为了让人乘上一个60的常数嘛 把一个树的点分树记录下来,然后看看询问的两个点彼此相同的最后一个父亲是谁,把这 ... 
- 「SCOI2010」幸运数字
		传送门 Luogu 解题思路 首先构造出所有的幸运数字. 然后考虑一个幸运数字会产生多少贡献. 对于一个数 \(x\),它在区间 \([l,r]\) 内的倍数的个数为 \(\lfloor \frac{ ... 
- 「SCOI2016」围棋 解题报告
		「SCOI2016」围棋 打CF后困不拉基的,搞了一上午... 考虑直接状压棋子,然后发现会t 考虑我们需要上一行的状态本质上是某个位置为末尾是否可以匹配第一行的串 于是状态可以\(2^m\)压住了, ... 
- 「SCOI2016」妖怪 解题报告
		「SCOI2016」妖怪 玄妙...盲猜一个结论,然后过了,事后一证,然后假了,数据真水 首先要最小化 \[ \max_{i=1}^n (1+k)x_i+(1+\frac{1}{k})y_i \] \ ... 
随机推荐
- mui选择时间、选择日期
			完整代码: <header class="mui-bar mui-bar-nav"> <a class="mui-action-back mui-i ... 
- 在开发第一个Android应用之前需要知道的5件事:
			你能否详细讲述一下,在开发Android应用过程中每一阶段要用到的技能和编程语言? 建立一个Android应用程序可以归结为两个主要技能/语言:Java和Android系统.Java是Android的 ... 
- JFinal-美女图爬虫-一个不正经的爬虫代码
			去年我做了一个项目,大量使用爬虫抓取数据,使用JFinal+JSoup组合,抓取数据,数据清洗筛选,最终保存到数据库里,结构化. 今天,我发布一个不正经的爬虫项目,如果你对JSoup做爬虫感兴趣,可以 ... 
- jenkins只能同时构建2个Job怎么办?
			在jenkins 构建任务时,同时只能构建2个,如果两个没有job没有结束,构建第3个就会不执行: 提示: pending—Waiting for next available executor on ... 
- JavaSe-算数运算符
			算数运算符包括:+.-.*./.%.++.-- 代码: package com.java.chap02; public class Demo07 { public static void main(S ... 
- duboo 配置文件
			官方文档 http://dubbo.apache.org/en-us/docs/user/quick-start.html 自己的 <?xml version="1.0" e ... 
- C#之winform实现文件拖拽功能【转】
			将一个文件拖拽到窗体的某个控件时,将该控件的路径显示在该控件上,只要拿到了路径自然可以读取文件中的内容了 将一个控件的属性AllowDrop设置为true,然后添加DragDrop.DragEnter ... 
- Python——print用法详解
			1.print语法格式 print()函数具有丰富的功能,详细语法格式如下:print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=Fa ... 
- css实现页面文字不换行、自动换行、强制换行
			强制不换行 div{ white-space:nowrap; } 自动换行 div{ word-wrap: break-word; word-break: normal; } 强制英文单词断行 div ... 
- Return Largest Numbers in Arrays-freecodecamp算法题目
			Return Largest Numbers in Arrays(找出多个数组中的最大数) 要求 大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组. 思路 用 ... 
