[NOI.AC#41]最短路 线性基
题解
如果不加边,两个点之间的长度是唯一的(只能走最短路径),因为如果重复走,就异或掉了。
因此,先DFS预处理一下每个点到根的距离 \(d[x]\) ,那么 \(x,y\) 之间的距离为 $d[x] \oplus d[y] $
对于每条新建的边 \((u,v,w)\) ,它实际上增加了一个环,如果没有范围限制,那就变成了[WC2011]最大XOR和路径(BZOJ2115)。
按照它的思路,我们对每个环(权值为 \(W[i]=d[u[i]]\oplus d[v[i]]\oplus w[i]\))构造线性基,考虑如何保证满足范围限制
将询问离线,并根据右端点排序(挂链表),然后按顺序扫描边数组 \(W[i]\) ,对于二进制基底 \(p[i]\) ,定义 \(q[i]\) 为它的位置,显然为了满足范围限制, \(q[i]\) 越大越好。因此从大到小枚举 \(i\) ,每遇到一个 \(q[i]\) 比当前位置小的,我们将其与之交换,然后多出来的 \(p[i]\) 再往下插入线性基。
处理答案时,从高位向低位贪心,如果 \(q[i]\) 在范围内就可以加入。
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i(a);i<=(b);++i)
#define dbg(...) fprintf(stderr,__VA_ARGS__)
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int>pii;
template<typename T,typename U>inline char smin(T&x,const U&y){return x>y?x=y,1:0;}
template<typename T,typename U>inline char smax(T&x,const U&y){return x<y?x=y,1:0;}
namespace IOManager{
const unsigned int iSize(131072),oSize(65536);
char buf[iSize],wbuf[oSize+128],*iT=buf+iSize,*iS=iT-1,*oS=wbuf-1,*oT=wbuf+oSize;
struct FastIO{
inline char gc(){
if(++iS==iT)fread(iS=buf,1,iSize,stdin);return *iS;
}
template<typename T>
inline void read(T&w){register char c,p=0;
while(isspace(c=gc()));if(c=='-')p=1,c=gc();w=c^48u;
while(isdigit(c=gc()))w=w*10+(c^48u);if(p)w=-w;
}
inline int read(){register int x;return read(x),x;}
inline void flush(){fwrite(wbuf,1,oS-wbuf+1,stdout);oS=wbuf-1;}
~FastIO(){flush();}
inline FastIO&operator<<(const char&c){if(oS>oT)flush();*++oS=c;}
inline void putstr(const string&s){
const int l=s.length();
if(oS>oT)flush();
for(int i=0;i<l;++i)*++oS=s[i];
}
template<typename T>
inline FastIO&operator<<(T x){
static char stk[30];int top=0;
if(oS>oT)flush();
if(x==0)return *++oS='0',*this;
if(x<0)x=-x,*++oS='-';
for(;x;x/=10)stk[++top]=x%10^48;
while(top)*++oS=stk[top--];
return*this;
}
};
}IOManager::FastIO io;
#define read io.read
const int n=read(),m=read(),Q=read(),N=3e5+5;
vector<int>g[N];
int head[N],tot,d[N],w[N],r[N],l[N],p[33],q[33],ans[N];
struct node{int v,w,nxt;}e[N<<1];
inline void add(int x,int y,int z){e[++tot]=(node){y,z,head[x]};head[x]=tot;}
inline void dfs(int x,int fa){for(int i=head[x];i;i=e[i].nxt)if(e[i].v!=fa)d[e[i].v]=d[x]^e[i].w,dfs(e[i].v,x);}
int main(){
REP(i,2,n){
int x=read(),y=read(),z=read();
add(x,y,z),add(y,x,z);
}
dfs(1,0);
REP(i,1,m)w[i]=d[read()]^d[read()]^read();
REP(i,1,Q){
ans[i]=d[read()]^d[read()];l[i]=read();g[read()].push_back(i);
}
REP(t,1,m){
int x=w[t],r=t;
for(int i=30;~i;--i)if(x>>i&1){
if(!p[i]){p[i]=x,q[i]=r;break;}
if(q[i]<r)swap(p[i],x),swap(q[i],r);
x^=p[i];
}
for(int k:g[t])for(int i=30;~i;--i)if(q[i]>=l[k])smin(ans[k],ans[k]^p[i]);
}
REP(i,1,Q)io<<ans[i]<<'\n';
return 0;
}
[NOI.AC#41]最短路 线性基的更多相关文章
- NOIAC41 最短路(线性基)
/* 暴力可以st表维护线性基, 从而复杂度两个log 实际上我们可以离线来做, 并且记录可行最右值, 就是一个log的了 */ #include<cstdio> #include< ...
- BZOJ_2844 albus就是要第一个出场 【线性基】
一.题目 albus就是要第一个出场 二.分析 非常有助于理解线性基的一题. 构造线性基$B$后,如果$|A| > |B|$,那么就意味着有些数可以由$B$中的数异或出来,而多的数可以取或者不取 ...
- BZOJ_2115 [Wc2011] Xor 【图上线性基】
一.题目 [Wc2011] Xor 二.分析 比较有意思的一题,这里也学到一个结论:$1$到$N$的任意一条路径异或和,可以是一个任意一条$1$到$N$的异或和与图中一些环的异或和组合得到.因为一个数 ...
- HDU_3949 XOR 【线性基】
一.题目 XOR 二.分析 给定$N$个数,问它的任意子集异或产生的数进行排列,求第K小的数. 构造出线性基$B$后,如果$|B| < N$,那么代表N个数中有一个数是可以由线性基中的其他数异或 ...
- BZOJ 2844 albus就是要第一个出场 ——高斯消元 线性基
[题目分析] 高斯消元求线性基. 题目本身不难,但是两种维护线性基的方法引起了我的思考. void gauss(){ k=n; F(i,1,n){ F(j,i+1,n) if (a[j]>a[i ...
- SCOI2016幸运数字(树剖/倍增/点分治+线性基)
题目链接 loj luogu 题意 求树上路径最大点权异或和 自然想到(维护树上路径)+ (维护最大异或和) 那么有三种方法可以选择 1.树剖+线性基 2.倍增+线性基 3.点分治+线性基 至于线性基 ...
- ACM-ICPC 2017 Asia Xi'an A XOR (线性基+线段树思想)
题目链接 题意;给个数组,每次询问一个区间你可以挑任意个数的数字异或和 然后在或上k的最大值 题解:线性基不知道的先看这个,一个线性基可以log的求最大值把对应去区间的线性基求出来然后用线段树维护线性 ...
- Codeforces 938G Shortest Path Queries [分治,线性基,并查集]
洛谷 Codeforces 分治的题目,或者说分治的思想,是非常灵活多变的. 所以对我这种智商低的选手特别不友好 脑子不好使怎么办?多做题吧-- 前置知识 线性基是你必须会的,不然这题不可做. 推荐再 ...
- 51Nod1577 异或凑数 线性基 构造
国际惯例的题面:异或凑出一个数,显然是线性基了.显然我们能把区间[l,r]的数全都扔进一个线性基,然后试着插入w,如果能插入,则说明w不能被这些数线性表出,那么就要输出"NO"了. ...
随机推荐
- js 异步加载的方式
js 异步加载的方式 渲染引擎遇到 script 标签会停下来,等到执行完脚本,继续向下渲染 defer 是“渲染完再执行”,async 是“下载完就执行”,defer 如果有多个脚本,会按照在页面中 ...
- POJ——T 1988 Cube Stacking
http://poj.org/problem?id=1988 Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 25865 ...
- 怎样只接受固定长度数组为参数 & 数组形参
注意,对于多维数组的情况.
- VC:当前不会命中断点,还没有为该文档载入不论什么符号
VS2013中设置的断点无效:"当前不会命中断点,还没有为该文档载入不论什么符号".问题主要出在没有生成调试信息.解决方法例如以下: (1)项目-〉属性-〉配置属性-〉C/C++- ...
- 使用maven运行单元測试总结
maven本身没有单元測试框架,可是maven的default生命周期的test阶段绑定了maven-surefire-plugin插件,该插件能够调用Junit3.Junit4.TestNG等Jav ...
- java基础 this keyword!
为了程序的可读性,通常将一个类中的表示同一属性的变量进行统一的命名.可是这样做又会导致成员变量与局部变量名字冲突导致无法訪问成员变量.为了解决问题,java中引入了this这个keyword!所以th ...
- [Java开发之路](6)File类的使用
1. 构造方法 构造方法 描写叙述 File(String pathname) 通过将给定的路径名字符串转换为抽象路径名来创建一个新的文件实例. File(String parent , String ...
- 创建一个基于ViSP的图片显示程序
创建一个图片读取,并在windows下窗口显示的程序. #include <visp/vpDisplayD3D.h> #include <visp/vpDisplayGDI.h> ...
- 二分法查找 js 算法
二分法查找算法:采用二分法查找时,数据需是排好序的.主要思想是:(设查找的数组区间为array[s, e])(1)确定该区间的中间位置m(2)将查找的值T与array[m]比较,若相等,查找成功返回此 ...
- 【Django】Session
目录 介绍 Django中操作Session @ 介绍 Cookie虽然在一定程度上解决了"保持状态"的需求,但是由于Cookie本身最大支持4096字节,以及Cookie本身保存 ...