【线性基合并 树链剖分】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 ...
随机推荐
- 笔记-JavaWeb学习之旅19
Redis:redis是一款高性能的NOSQL系列的非关系型数据库 NOSQL: Not Only SQL ,意即"不仅仅是SQL",是一项全新的数据库理念,泛指非关系型数据库 r ...
- JavaScript进阶 - 第3章 一起组团(数组)
第3章 一起组团(数组) 3-1 一起组团(什么是数组) 我们知道变量用来存储数据,一个变量只能存储一个内容.假设你想存储10个人的姓名或者存储20个人的数学成绩,就需要10个或20个变量来存储,如果 ...
- tomcat7 fail to start inside Ubuntu Docker container
The tomcat startup script needs some special privileges. Concrete it needs to check all running proc ...
- 看完这篇文章,我奶奶都懂了https的原理
本文在个人技术博客同步发布,详情可猛戳 亦可扫描屏幕右方二维码关注个人公众号 Http存在的问题 上过网的朋友都知道,网络是非常不安全的.尤其是公共场所很多免费的wifi,或许只是攻击者的一个诱饵 ...
- SLF4J user manual 专题
System Out and Err Redirected to SLF4J The sysout-over-slf4j module allows a user to redirect all ca ...
- 在 WPF 中的线程
线程处理使程序能够执行并发处理,以便它可以做多个操作一次.节省开发人员从线程处理困难的方式,设计了 WPF (窗口演示文稿基金会).这篇文章可以帮助理解线程在 WPF 中的正确用法. WPF 内部线程 ...
- C#入门笔记3 表达式及运算符2
关系运算符,也称布尔比较运算符 注:var1为bool类型,var2与var3可以是其它类型.[数据类型看下一节] 运算符 类别 示例表达式 结果说明 == 二元 var1=var2==var3 如果 ...
- Hi,bro
这是我第一次写部落格,也是我刚开始学python,希望我以后能把To Do List 做好,也希望大家可以好好学习,为了以后good life去努力,Do SomeThing OK?
- 监听textarea数值变化
监听textarea数值变化 $('#id').bind('input propertychange', function(){ //TODO });
- react中constructor和super()以及super(props)的区别。
react中这两个API出镜率超级高,但是一直不太懂这到底是干嘛的,有什么用:今天整理一下,方便自己查看同时方便大家. 1.constructor( )-----super( )的基本含义 const ...