BZOJ 4568: [Scoi2016]幸运数字 [线性基 倍增]
4568: [Scoi2016]幸运数字
题意:一颗带点权的树,求树上两点间异或值最大子集的异或值
显然要用线性基
可以用倍增的思想,维护每个点向上\(2^j\)个祖先这些点的线性基,求lca的时候合并起来就行了
复杂度\(O(nlogn60*60)\)
注意这是点权,特判x==y的情况,需要插入a[x]
还可以用点分治和树链剖分
我的代码好慢啊...但是很好写啊
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long ll;
#define pii pair<int, int>
#define fir first
#define sec second
const int N=2e4+5;
inline ll read() {
char c=getchar(); ll x=0, f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
}
int n, Q, u, v; ll a[N];
struct edge{int v, ne;}e[N<<1];
int cnt=1, h[N];
inline void ins(int u, int v) {
e[++cnt]=(edge){v, h[u]}; h[u]=cnt;
e[++cnt]=(edge){u, h[v]}; h[v]=cnt;
}
namespace lb{
struct meow {
ll p[62];
meow(){memset(p, 0, sizeof(p));}
ll operator [](int x) {return p[x];}
bool insert(ll val) {
for(int i=60; i>=0; i--)
if(val & (1LL<<i)) {
if(p[i]) val ^= p[i];
else {p[i]=val; break;}
}
return val>0;
}
void merge(meow &a) {
for(int i=60; i>=0; i--) if(a[i]) insert(a[i]);
}
ll getmax() {
ll ans=0;
for(int i=60; i>=0; i--) ans = max(ans, ans^p[i]);
return ans;
}
void print() {
for(int i=60; i>=0; i--) if(p[i]) printf("p %d %lld\n",i,p[i]);
puts("");
}
}b[N][17];
}using lb::b; using lb::meow;
int fa[N][17], deep[N];
void dfs(int u) {
for(int i=1; (1<<i)<=deep[u]; i++) {
fa[u][i] = fa[ fa[u][i-1] ][i-1];
b[u][i].merge(b[u][i-1]); b[u][i].merge(b[ fa[u][i-1] ][i-1]);
}
for(int i=h[u];i;i=e[i].ne)
if(e[i].v != fa[u][0]) {
fa[e[i].v][0]=u;
deep[e[i].v]=deep[u]+1;
b[e[i].v][0].insert(a[u]);
dfs(e[i].v);
}
}
meow lca(int x, int y) { //printf("lca %d %d\n",x,y);
meow now;
if(x==y) {now.insert(a[x]); return now;}
if(deep[x]<deep[y]) swap(x, y);
int bin=deep[x]-deep[y];
for(int i=0; i<15; i++)
if((1<<i)&bin) now.merge(b[x][i]), x=fa[x][i];
if(x==y) return now;
for(int i=14; i>=0; i--)
if(fa[x][i] != fa[y][i]) now.merge(b[x][i]), now.merge(b[y][i]), x=fa[x][i], y=fa[y][i];
now.merge(b[x][0]); now.insert(a[y]);
//puts("now");now.print();
return now;
}
ll Que(int x, int y) {
return lca(x, y).getmax();
}
int main() {
freopen("in","r",stdin);
n=read(); Q=read();
for(int i=1; i<=n; i++) a[i]=read(), b[i][0].insert(a[i]);
for(int i=1; i<n; i++) ins(read(), read());
dfs(1);
//for(int i=1; i<=n; i++)
// for(int j=0; (1<<j)<=deep[i]; j++) printf("hi %d %d %d\n",i,j,fa[i][j]), b[i][j].print();
for(int i=1; i<=Q; i++) printf("%lld\n", Que(read(), read()));
}
BZOJ 4568: [Scoi2016]幸运数字 [线性基 倍增]的更多相关文章
- BZOJ 4568 [Scoi2016]幸运数字 ——线性基 倍增
[题目分析] 考虑异或的最大值,维护线性基就可以了. 但是有多次的询问,树剖或者倍增都可以. 想了想树剖动辄数百行的代码. 算了,我还是写倍增吧. 注:被位运算和大于号的优先级坑了一次,QaQ [代码 ...
- 洛谷P3292 [SCOI2016]幸运数字 线性基+倍增
P3292 [SCOI2016]幸运数字 传送门 题目描述 A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以纪念碑的形式矗立在 ...
- P3292 [SCOI2016]幸运数字 [线性基+倍增]
线性基+倍增 // by Isaunoya #include <bits/stdc++.h> using namespace std; #define rep(i, x, y) for ( ...
- BZOJ4568: [Scoi2016]幸运数字(线性基 倍增)
题意 题目链接 Sol 线性基是可以合并的 倍增维护一下 然后就做完了?? 喵喵喵? // luogu-judger-enable-o2 #include<bits/stdc++.h> # ...
- BZOJ.4516.[SCOI2016]幸运数字(线性基 点分治)
题目链接 线性基可以\(O(log^2)\)暴力合并.又是树上路径问题,考虑点分治. 对于每个点i求解 LCA(u,v)==i 时的询问(u,v),只需求出这个点到其它点的线性基后,暴力合并. LCA ...
- bzoj 4568: [Scoi2016]幸运数字
4568: [Scoi2016]幸运数字 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 848 Solved: 336[Submit][Status ...
- P3292 [SCOI2016]幸运数字 线性基
正解:线性基+倍增 解题报告: 先放下传送门QAQ 然后这题,其实没什么太大的技术含量,,,?就几个知识点套在一起,除了代码长以外没任何意义,主要因为想复习下线性基的题目所以还是写下,,, 随便写下思 ...
- BZOJ 4568: [Scoi2016]幸运数字(倍增+线性基)
传送门 解题思路 异或最大值肯定线性基了,树上两点那么就倍增搞一搞,就维护每个点到各级祖先的线性基,时间复杂度\(O(nlog^3n)\),并不知道咋过去的. 代码 #include<iostr ...
- BZOJ 4568 [Scoi2016]幸运数字(树链剖分 + 异或线性基)
题目链接 BZOJ 4568 考虑树链剖分+线段树维护每一段区域的异或线性基 对于每个询问,求出该点集的异或线性基.然后求一下这个线性基里面能异或出的最大值即可. #include <bits ...
随机推荐
- Matrix Chain Multiplication(表达式求值用栈操作)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1082 Matrix Chain Multiplication Time Limit: 2000/100 ...
- malloc函数用法
malloc函数用法 函数声明(函数原型): void *malloc(int size); 说明:malloc 向系统申请分配指定size个字节的内存空间.返回类型是 void* 类型.void* ...
- QT 操作 excel 教程
前言:环境 win7 64位,QT4.8.5,QT Creator 在 .pro 文件中加入语句"CONFIG+=qaxcontainer"; 源码如下: //main.cpp # ...
- setTimeout()方法,你真的懂吗?
今天在群里看到了一道经典的javascript题型,之前也遇到过,可是再次遇到时,还是做错,还是不理解,因此这里来做个笔记吧! 不说了,直接上代码吧 for(var i=1; i<=9; i++ ...
- 任务驱动 搭建SSM开发环境
本篇主要阐述(IntelliJ IDEA + Maven + Spring + Spring MVC + Mybatis)搭建 为什么想要搭建ssm? 近期正好自己有一个小的点子要实现,恰好这学期开了 ...
- [翻译]HTML5 - 会话历史和导航
原文为:https://w3c.github.io/html/browsers.html#session-history-and-navigation 一.浏览上下文的会话历史记录 浏 ...
- PageRank_网页排名_MapReduceJava代码实现思路
PageRank 1. 概念 2. 原理 3. java代码实现思路 1.定义收敛标准 每次算出新的pr-oldpr=差值 ,所有页面的差值累加 ,除以pagecou ...
- 什么是MVC ?
记得第一次面试phper(php是对我来说可以快速上手的另一web开发语言),人家问我MVC,我只知道m就是model,v就是view,c就是Controller,具体把其它的认识我是一无所知,结果我 ...
- SSH中post提交表单action中文乱码问题
我的问题对应的解决方案是:web.xml中filter的顺序问题[置顶].需要将编码过滤器放置在所有过滤器之前. 在解决这个问题途中学习到的东西: 解决方案总结(post中文乱码): 前后台编码方式一 ...
- python-虎扑爬虫
Python作为一个高级编程语言,不知从何时起就在圈子里流行起来了.个人也是图个鲜,跟上时代步伐学习了一下."鲁迅"说过:不能学以致用,就是耍流氓.我用python对虎扑论坛作了一 ...