[SCOI 2016]幸运数字
Description
Input
Output
输出需要包含 q 行,每行包含 1 个非负整数,表示这名旅行者可以保留的最大幸运值。
Sample Input
11 5 7 9
1 2
1 3
1 4
2 3
1 4
Sample Output
11
题解
线性基+点分治。
这两个都是最近才接触的,正好有道题结合起来了。
我们每次找到重心,处理与重心相关的路径。
处理时我们将重心到每个节点这一段的$xor$存起来,然后找到所有经过重心的路径。
我是在遍历以重心$G$为根的一个子树过程中,找到与这棵子树中节点$u$有关的询问$(u,v)$,判断是否在之前遍历过的以重心为根的其他子树中出现过,如果出现过,我们可以将$G->u$和$G->v$这两段的线性基合并。找到合并后的线性基中的最大值就好了。对于合并,直接暴力拆开一个线性基,一个一个插入到另一个线性基中。
处理完这棵子树之后,再遍历一遍,打上访问过的标记。这样保证所有询问都只计算过一次。
注意,处理完这个重心之后,清空标记时,不要$memset$,直接再遍历一遍就好了,快得多。
值得注意的是,要单独考虑与$G$有关的询问如$(G,v)$,因为重心$G$没标记访问过。(当然了,你可以找完重心后就马上把重心标记访问,效果是一样的,这个询问也只会遍历一次。因为重心是不会被访问的)
另外注意单独考虑$(u,u)$的询问。
//It is made by Awson on 2017.9.22
#include <set>
#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define LL long long
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define sqr(x) ((x)*(x))
using namespace std;
const int N = ;
const int Q = ;
const int INF = ~0u>>;
LL st[];
int Read() {
int sum = ;
char ch = getchar();
while (ch < '' || ch > '') ch = getchar();
while (ch >= '' && ch <= '') sum = (sum<<)+(sum<<)+ch-, ch = getchar();
return sum;
} struct base {
LL a[];
void insert(LL x) {
for (int i = ; i >= ; i--)
if (x&st[i]) {
if (!a[i]) {
a[i] = x;
break;
}
else x ^= a[i];
}
}
LL getmax() {
LL maxn = ;
for (int i = ; i >= ; i--)
maxn = Max(maxn, (maxn^a[i]));
return maxn;
}
void clean() {
for (int i = ; i >= ; i--)
a[i] = ;
}
void copy(base b) {
for (int i = ; i >= ; i--)
a[i] = b.a[i];
}
void merge(base b) {
for (int i = ; i >= ; i--) {
insert(b.a[i]);
}
}
}ba[N+], tmp;
int n, q, u, v;
LL g[N+];
struct tt {
int to, next;
}edge[N*+];
int path[N+], top;
struct question {
int v, id, next;
}que[Q*+];
int pathq[N+], topq;
LL ans[Q+];
int size[N+], mx[N+], minsize, root;
bool vis[N+];
bool judge[N+]; void add(int u, int v) {
edge[++top].to = v;
edge[top].next = path[u];
path[u] = top;
}
void addq(int u, int v, int id) {
que[++topq].v = v;
que[topq].id = id;
que[topq].next = pathq[u];
pathq[u] = topq;
}
void get_size(int u, int fa) {
size[u] = , mx[u] = ;
for (int i = path[u]; i; i = edge[i].next)
if (edge[i].to != fa && !vis[edge[i].to]) {
get_size(edge[i].to, u);
size[u] += size[edge[i].to];
mx[u] = Max(mx[u], size[edge[i].to]);
}
}
void get_root(int r, int u, int fa) {
mx[u] = Max(mx[u], size[r]-size[u]);
if (mx[u] < minsize) minsize = mx[u], root = u;
for (int i = path[u]; i; i = edge[i].next)
if (edge[i].to != fa && !vis[edge[i].to])
get_root(r, edge[i].to, u);
}
void get_ans(int r, int u, int fa) {
ba[u].copy(ba[fa]);
ba[u].insert(g[u]);
for (int i = pathq[u]; i; i = que[i].next)
if (judge[que[i].v]) {
tmp.copy(ba[u]);
tmp.merge(ba[que[i].v]);
ans[que[i].id] = tmp.getmax();
}
else if (que[i].v == r) {
ans[que[i].id] = ba[u].getmax();
}
for (int i = path[u]; i; i = edge[i].next)
if (edge[i].to != fa && !vis[edge[i].to])
get_ans(r, edge[i].to, u);
}
void get_update(int u, int fa) {
judge[u] = !judge[u];
for (int i = path[u]; i; i = edge[i].next)
if (edge[i].to != fa && !vis[edge[i].to])
get_update(edge[i].to, u);
}
void doit(int x) {
minsize = INF;
get_size(x, );
get_root(x, x, );
vis[root] = ;
ba[root].clean();
ba[root].insert(g[root]);
for (int i = path[root]; i; i = edge[i].next)
if (!vis[edge[i].to]) {
get_ans(root, edge[i].to, root);
get_update(edge[i].to, root);
}
for (int i = path[root]; i; i = edge[i].next)
if (!vis[edge[i].to])
get_update(edge[i].to, root);
for (int i = path[root]; i; i = edge[i].next)
if (!vis[edge[i].to])
doit(edge[i].to);
}
void work() {
n = Read(), q = Read();
for (int i = ; i <= n; i++) scanf("%lld", &g[i]);
for (int i = ; i < n; i++) {
u = Read(), v = Read();
add(u, v), add(v, u);
}
for (int i = ; i <= q; i++) {
u = Read(), v = Read();
if (u != v) addq(u, v, i), addq(v, u, i);
else ans[i] = g[u];
}
doit();
for (int i = ; i <= q; i++) printf("%lld\n", ans[i]);
}
int main() {
st[] = ;
for (int i = ; i < ; i++)
st[i] = st[i-]<<;
work();
return ;
}
[SCOI 2016]幸运数字的更多相关文章
- bzoj 4568 [SCOI 2016] 幸运数字
题目大意 给定一棵\(n\)个点的树,每个点有权值 \(q\)次询问树上路径中 每个点权值可选可不选的最大异或和 \(n\le 2*10^4,q\le 2*10^5,val[i]\le 2^{60}\ ...
- Scoi 2010 幸运数字
[题目描述]在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认为,于是他定义自己的“幸运号码”是十进制表示中只包含数字6和8的那些号码,比如68,666,888都是“幸运号码”!但是这种“幸 ...
- BZOJ 1853 【Scoi2010】 幸运数字
Description 在中国,很多人都把6和8视为是幸运数字!lxhgww也这样认 为,于是他定义自己的"幸运号码"是十进制表示中只包含数字6和8的那些号码,比如68,666,8 ...
- BZOJ 4568 幸运数字
题目传送门 4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MB Description A 国共有 n 座城市,这些城市由 n-1 ...
- BZOJ 1853: [Scoi2010]幸运数字
1853: [Scoi2010]幸运数字 Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 2117 Solved: 779[Submit][Status] ...
- 【BZOJ-4568】幸运数字 树链剖分 + 线性基合并
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 238 Solved: 113[Submit][Status ...
- 【BZOJ-1853&2393】幸运数字&Cirno的完美算数教室 容斥原理 + 爆搜 + 剪枝
1853: [Scoi2010]幸运数字 Time Limit: 2 Sec Memory Limit: 64 MBSubmit: 1817 Solved: 665[Submit][Status] ...
- BZOJ1853 [Scoi2010]幸运数字
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 【bzoj1853】 Scoi2010—幸运数字
http://www.lydsy.com/JudgeOnline/problem.php?id=1853 (题目链接) 今天考试考了容斥,结果空知道结论却不会写→_→ 题意 求区间中不含6,8两个数字 ...
随机推荐
- vue2 前端搜索实现
项目数据少的时候,搜索这样的小事情就要交给咱们前端来做了,重要声明,适用于小项目!!!!! 其实原理很简单,小demo是做搜索市区名称或者按照排名搜索. <div> <input t ...
- bzoj千题计划243:bzoj2325: [ZJOI2011]道馆之战
http://www.lydsy.com/JudgeOnline/problem.php?id=2325 设线段树节点区间为[l,r] 每个节点维护sum[0/1][0/1] 从l的A/B区域到r的 ...
- 服务器数据恢复方法_存储raid硬盘离线数据恢复案例
[故障描述]某法院的一台HP-P4500的存储系统,底层是12块1TB的硬盘组的RAID.其中每6个1TB的盘一组,第一组的前面一部分组了一个RAID0+1,是存放HP-P4500嵌入式系统,接着组了 ...
- 【Fungus入门】10分钟快速构建Unity中的万能对话系统 / 叙事系统 / 剧情系统
我真的很久没有写过一个完整的攻略了(笑),咸鱼了很久之后还是想来写一个好玩的.这次主要是梳理一下Unity的小众插件Fungus的核心功能,并且快速掌握其使用方法. 官方文档:http://fungu ...
- Python之旅_计算机基础入门
一.计算机基础 1.Python是编程语言 语言:一种事物与另一种事物沟通的介质. 编程语言:程序员与计算机沟通的介质. 什么是编程:程序员用编程语言把自己的逻辑思想下来,编程的结果就是一堆文件. 为 ...
- java对象转字节数组,获取泛型类
对象转字节数组,字节数组在恢复成对象 Test.java class Test { public static void main(String args[]) throws IOException, ...
- React Native学习(九)—— 使用Flexbox布局
本文基于React Native 0.52 Demo上传到Git了,有需要可以看看,写了新内容会上传的.Git地址 https://github.com/gingerJY/React-Native-D ...
- 新概念英语(1-3)Sorry, sir
Does the man get his umbrella back? A:My coat and my umbrella please. B:Here is my ticket. A:Thank y ...
- Spark入门(1-3)Spark的重要概念
1.什么是弹性分布式数据集? Spark提出了RDD(Resilient Distributed Datasets)这么一个全新的概念,RDD弹性分布式数据集是并行.容错的分布式数据结构:可以将RDD ...
- maven快速下载jar镜像
<!--国内镜像--><mirror> <id>CN</id> <name>OSChina Central</name> ...