qoj 1168 题解及线性基相关探究
简要题意#
给定 个点 条边的无向联通图 ,边有边权。其中 的距离 定义为 的最大 路径。
次询问 ,求 的值。
。
一些转化#
首先必然套用 P4151 的结论:设所有环的异或和构成空间为 。 为 的任意一条路径的异或和。
则 。考虑记变换 。
,由于一些深刻的理论,我们接下来对 的关系进行探究。
线性基上的 min/max 探究#
我们给出如下结论:
简而言之:
下面证明 ,其他同理。下面过程为了迎合 oi 中的线性基算法,可能有少许不严谨。
记 的线性基的构成元素为 ,但是这里我们令 有二进制最高位 ,并把剩下缺的 补齐为 。
考察 运算在 的每一位中的决策,这对于每一位是一致的,即:
当第 位为 时,异或上 。当第 位为 时,不异或上 。
则是:当第 位为 时,不异或上 。当第 位为 时,异或上 。
我们把 和 在第 位的决策合并起来:
:当 第 位为 时,不异或上 。当第 位为 时,异或上 。
我们就得出了 。
更进一步的,显然我们能基于上面三个推出:
并且,我们注意到 是一个线性变换,即根据 。这将很有用。
原题解法#
首先容易根据前置知识求出 ,其中 为线性基, 满足:。
根据上述理论,我们有:。
于是
于是单次询问就容易处理了,上个线性基板子即可。
//qoj 1168
//https://qoj.ac/contest/537/problem/1168
#include<bits/stdc++.h>
#define LL long long
#define fr(x) freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);
using namespace std;
const int N=1e5+5;
struct edge{int to,nex,w;}e[N<<1];
int n,m,q,tot,head[N],B[31],a[N];bool v[N];
inline void add(int u,int v,int w)
{
e[++tot]={v,head[u],w};head[u]=tot;
e[++tot]={u,head[v],w};head[v]=tot;
}
inline void ins(int x)
{
for(int i=30;i>=0;i--)
if((x>>i)&1)
{
if(!B[i]){B[i]=x;break;}
x^=B[i];
}
}
inline int que(int x){for(int i=30;i>=0;i--) if((x^B[i])<x) x^=B[i];return x;}
void dfs(int x,int s)
{
a[x]=s;v[x]=1;
for(int i=head[x];i;i=e[i].nex)
{
int to=e[i].to;
!v[to]?dfs(to,s^e[i].w):ins(s^a[to]^e[i].w);
}
}
int main()
{
scanf("%d%d%d",&n,&m,&q);
for(int u,v,w;m--;) scanf("%d%d%d",&u,&v,&w),add(u,v,w);
dfs(1,0);int mx=0;
for(int i=30;i>=0;i--) if((mx^B[i])>mx) mx^=B[i];
for(int i=1;i<=n;i++) a[i]^=a[i-1];
for(int l,r;q--;)
{
scanf("%d%d",&l,&r);int x=r-l,ans=0;
if(x&1) ans^=que(a[r]^a[l-1]);
if(((LL)x*(x+1)/2)&1) ans^=mx;printf("%d\n",ans);
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2023-10-25 竞赛图性质研究(强联通分量/哈密顿回路)