【线性基合并 树链剖分】bzoj4568: [Scoi2016]幸运数字
板子题
Description
Input
Output
输出需要包含 q 行,每行包含 1 个非负整数,表示这名旅行者可以保留的最大幸运值。
题目分析
树剖/倍增的板子题
想用树剖来做一做,然而TLE了好几发。
发现自己常数意识太差,每次query时候都开一个线性基,活生生浪费10s+
#include<bits/stdc++.h>
#define ENS //__attribute__((optimize("-O2")))
#define NES //__attribute__((optimize("-O2"))) //__inline__ __attribute__((always_inline))
typedef long long ll;
const int maxn = ;
const int maxm = ;
const int maxq = ; struct Linear
{
ll p[];
Linear(){memset(p, , sizeof p);}
NES void insert(ll c)
{
for (int i=, chk=; i>=&&!chk; i--)
if (c>>i){
if (p[i]) c ^= p[i];
else p[i] = c, chk = ;
}
}
NES void merge(Linear b)
{
for (int i=; i>=; i--)
if (b.p[i]) insert(b.p[i]);
}
NES ll max()
{
ll ret = ;
for (int i=; i>=; i--)
if ((ret^p[i]) > ret) ret ^= p[i];
return ret;
}
}f[maxn<<];
struct node
{
int fa,son,top,tot;
}a[maxn];
int n,q,chain[maxn],chTot,dep[maxn];
int edgeTot,head[maxn],nxt[maxm],edges[maxm];
ll g[maxn],cnVal[maxn]; template <typename T> NES void read(T&x)
{
char cu=getchar();x=;bool fla=;
while(!isdigit(cu)){if(cu=='-')fla=;cu=getchar();}
while(isdigit(cu))x=x*+cu-'',cu=getchar();
if(fla)x=-x;
}
void write(ll x){if (x/) write(x/);putchar(''+x%);}
void writeln(ll x){write(x), putchar('\n');}
NES void addedge()
{
int u,v;
read(u), read(v);
edges[++edgeTot] = v, nxt[edgeTot] = head[u], head[u] = edgeTot;
edges[++edgeTot] = u, nxt[edgeTot] = head[v], head[v] = edgeTot;
}
void dfs1(int x, int fa)
{
a[x].son = a[x].top = -, a[x].fa = fa;
a[x].tot = , dep[x] = dep[fa]+;
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v!=fa){
dfs1(v, x), a[x].tot += a[v].tot;
if (a[x].son==-||a[a[x].son].tot < a[v].tot) a[x].son = v;
}
}
}
void dfs2(int x, int top)
{
a[x].top = top, chain[x] = ++chTot, cnVal[chTot] = g[x];
if (a[x].son==-) return;
dfs2(a[x].son, top);
for (int i=head[x]; i!=-; i=nxt[i])
{
int v = edges[i];
if (v!=a[x].son&&v!=a[x].fa) dfs2(v, v);
}
}
void build(int rt, int l, int r)
{
if (l==r){
f[rt].insert(cnVal[l]);
return;
}
int mid = (l+r)>>;
build(rt<<, l, mid);
build(rt<<|, mid+, r);
f[rt] = f[rt<<], f[rt].merge(f[rt<<|]);
}
Linear query(int rt, int l, int r, int L, int R)
{
if (L <= l&&r <= R) return f[rt];
int mid = (l+r)>>;
if (L <= mid&&R > mid){ Linear tmp = query(rt<<, l, mid, L, R);
tmp.merge(query(rt<<|, mid+, r, L, R));
return tmp;
}else if (L <= mid) return query(rt<<, l, mid, L, R);
else if (R > mid) return query(rt<<|, mid+, r, L, R);
}
NES void queryChain()
{
Linear ret;
int x,y;
read(x), read(y);
while (a[x].top!=a[y].top)
{
if (dep[a[x].top] > dep[a[y].top]) std::swap(x, y);
ret.merge(query(, , n, chain[a[y].top], chain[y]));
y = a[a[y].top].fa;
}
if (dep[x] > dep[y]) std::swap(x, y);
ret.merge(query(, , n, chain[x], chain[y]));
writeln(ret.max());
}
ENS int main()
{
memset(head, -, sizeof head);
read(n), read(q);
for (int i=; i<=n; i++) read(g[i]);
for (int i=; i<n; i++) addedge();
dfs1(, ), dfs2(, );
build(, , n);
while (q--) queryChain();
return ;
}
END
【线性基合并 树链剖分】bzoj4568: [Scoi2016]幸运数字的更多相关文章
- 【BZOJ4568】幸运数字(线性基,树链剖分,ST表)
[BZOJ4568]幸运数字(线性基,树链剖分,ST表) 题面 BZOJ Description A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市 ...
- bzoj4568 [Scoi2016]幸运数字 线性基+树链剖分
A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游览 A ...
- [BZOJ4568][SCOI2016]幸运数字(倍增LCA,点分治+线性基)
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2131 Solved: 865[Submit][Statu ...
- BZOJ4568 [Scoi2016]幸运数字 【点分治 + 线性基】
题目链接 BZOJ4568 题解 选任意个数异或和最大,使用线性基 线性基插入\(O(logn)\),合并\(O(log^2n)\) 我们要求树上两点间异或和最大值,由于合并是\(O(log^2n)\ ...
- bzoj4568: [Scoi2016]幸运数字(LCA+线性基)
4568: [Scoi2016]幸运数字 题目:传送门 题解: 好题!!! 之前就看过,当时说是要用线性基...就没学 填坑填坑: %%%线性基 && 神犇 主要还是对于线性基的运用和 ...
- luogu P6088 [JSOI2015]字符串树 可持久化trie 线段树合并 树链剖分 trie树
LINK:字符串树 先说比较简单的正解.由于我没有从最简单的考虑答案的角度思考 所以... 下次还需要把所有角度都考察到. 求x~y的答案 考虑 求x~根+y~根-2*lca~根的答案. 那么问题变成 ...
- bzoj 2243: [SDOI2011]染色 线段树区间合并+树链剖分
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 7925 Solved: 2975[Submit][Status ...
- [BZOJ4568][Scoi2016]幸运数字 倍增+线性基
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1791 Solved: 685[Submit][Statu ...
- 2019.03.25 bzoj4568: [Scoi2016]幸运数字(倍增+线性基)
传送门 题意:给你一棵带点权的树,多次询问路径的最大异或和. 思路: 线性基上树?? 倍增维护一下就完了. 时间复杂度O(nlog3n)O(nlog^3n)O(nlog3n) 代码: #include ...
随机推荐
- 解决resignFirstResponder或者endEditing无效的办法
当你想要收回弹出的键盘时却发现平时用的resignFirstResponder和endEditing都失去作用时,应该考虑一下当前的TextField是否为第一响应者,如果不是第一响应者的话,自然下面 ...
- mySQL多表查询与事务
一.范式 1. 什么是范式 1.1 什么是范式 范式:设置一个科学的.规范的数据库,需要满足的一些规则 1.2 有哪些范式 共有:6大范式 第1范式:1NF 满足最基本的要求 第2范式:2NF 在1N ...
- 查看java 版本
执行 java -version 命令,如下图所示如果没有明确显示位数的,则说明是32位 C:\MyTools\jdk1.7.0\bin>java -version java version & ...
- php:一个题目,关于优先级,及$a++和$a=$a+1,
这几天常看到微博上转发的一条微博:就做了下,竟做错了,所以就试着分析了下~~ 这是微博: 这是代码: <?php $c = 3; $b = 6; if ($c = 4 || $b = 4) { ...
- storm maven-shade-plugin
storm-core pom <plugin> <groupId>org.apache.maven.plugins</groupId> <artifact ...
- NET中并行开发优化
NET中并行开发优化 让我们考虑一个简单的编程挑战:对大数组中的所有元素求和.现在可以通过使用并行性来轻松优化这一点,特别是对于具有数千或数百万个元素的巨大阵列,还有理由认为,并行处理时间应该与常规时 ...
- FloatHelper
function FloatHelper() { } FloatHelper.prototype.showFloater = function (Target, Title, Action, Acti ...
- MySQL 如何在一个语句中更新一个数值后返回该值 -- 自增长种子竞态问题处理
什么是竞态问题? 假设有一个计数器,首先当前值自增长,然后获取到自增长之后的当前值.自增长后的值有可能被有些操作用来当做唯一性标识,因此并发的操作不能允许取得相同的值. 为什么不能使用使用UPDATE ...
- 8.html表格相关的标记9.html表格实战《简单的网页布局》
<html> <head> <title>第八课标题表格</title> <meta charset="utf-8"> ...
- MUI获取文本框的值
MUI事件绑定注意父节点.子节点(也可以是标签选择器) js部分 html部分