#线段树分治,线性基,并查集#CF938G Shortest Path Queries
题目
给出一个连通带权无向图,边有边权,要求支持 \(q\) 个操作:
\(x\) \(y\) \(d\) 在原图中加入一条 \(x\) 到 \(y\) 权值为 \(b\) 的边
\(x\) \(y\) 把图中 \(x\) 到 \(y\) 的边删掉
\(x\) \(y\) 表示询问 \(x\) 到 \(y\) 的异或最短路
保证任意操作后原图连通无重边自环且操作均合法
\(n,m,q≤200000\)
分析
删除很难做,考虑线段树分治,
那么题目就转换成求某一时间点,
无向图的异或最短路,先构建一棵生成树,
那么环上边等于是将生成树异或值抵消掉,
用线性基求异或最小值
那么在并查集的基础上维护生成树点到根的距离即可
代码
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <map>
#define rr register
using namespace std;
const int N=200011; vector<int>K[N<<2]; struct five{int x,y,w,l,r;}e[N<<1];
struct rec{int x,y;}q[N]; map<pair<int,int>,int>uk;
int n,m,T,dep[N],f[N],d[N],stac[N],stad[N],tac[N],tad[N],staD[N],taD[N],tot,tod,toD,ans[N];
inline signed iut(){
rr int ans=0; rr char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
return ans;
}
inline void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
struct Vector_Space{
int re[30];
inline void BUILD(){memset(re,0,sizeof(re));}
inline void Insert(int x){
for (rr int i=29;~i;--i)
if ((x>>i)&1){
if (re[i]) x^=re[i];
else {re[i]=x; return;}
}
}
inline signed query(int x){
for (rr int i=29;~i;--i)
if ((x^re[i])<x) x^=re[i];
return x;
}
};
inline void update(int k,int l,int r,int x,int y,int z){
if (l==x&&r==y) {K[k].push_back(z); return;}
rr int mid=(l+r)>>1;
if (y<=mid) update(k<<1,l,mid,x,y,z);
else if (x>mid) update(k<<1|1,mid+1,r,x,y,z);
else update(k<<1,l,mid,x,mid,z),update(k<<1|1,mid+1,r,mid+1,y,z);
}
inline signed getf(int u){return f[u]==u?u:getf(f[u]);}
inline signed getd(int u){return f[u]==u?0:(d[u]^getd(f[u]));}
inline void dfs(int k,int l,int r,Vector_Space H){
rr int len=K[k].size(),Tot=tot,Tod=tod,ToD=toD;
for (rr int i=0;i<len;++i){
rr five t=e[K[k][i]];
rr int fa=getf(t.x),fb=getf(t.y);
rr int W=getd(t.x)^getd(t.y)^t.w;
if (fa==fb){H.Insert(W); continue;}
if (dep[fa]>dep[fb]) fa^=fb,fb^=fa,fa^=fb;
staD[++toD]=fa,taD[toD]=d[fa],d[fa]=W;
if (dep[fa]==dep[fb]){
stad[++tod]=fb,tad[tod]=dep[fb];
++dep[fb];
}
stac[++tot]=fa,tac[tot]=f[fa],f[fa]=fb;
}
rr int mid=(l+r)>>1;
if (l==r) ans[l]=H.query(getd(q[l].x)^getd(q[l].y));
else dfs(k<<1,l,mid,H),dfs(k<<1|1,mid+1,r,H);
for (;tot>Tot;--tot) f[stac[tot]]=tac[tot];
for (;tod>Tod;--tod) dep[stad[tod]]=tad[tod];
for (;toD>ToD;--toD) d[staD[toD]]=taD[toD];
}
signed main(){
n=iut(),m=iut();
for (rr int i=1;i<=n;++i) f[i]=i,dep[i]=1;
for (rr int i=1;i<=m;++i){
rr int x=iut(),y=iut(),w=iut();
if (x>y) x^=y,y^=x,x^=y;
e[i]=(five){x,y,w,0,-2},uk[make_pair(x,y)]=i;
}
for (rr int Q=iut();Q;--Q){
rr int opt=iut(),x=iut(),y=iut();
if (x>y) x^=y,y^=x,x^=y;
if (opt==1)
e[++m]=(five){x,y,iut(),T,-2},
uk[make_pair(x,y)]=m;
else if (opt==2){
rr int now=uk[make_pair(x,y)];
e[now].r=T-1;
}else q[T++]=(rec){x,y};
}
for (rr int i=1;i<=m;++i) if (e[i].r==-2) e[i].r=T;
for (rr int i=1;i<=m;++i)
if (e[i].l<=e[i].r) update(1,0,T,e[i].l,e[i].r,i);
rr Vector_Space H; H.BUILD(),dfs(1,0,T,H);
for (rr int i=0;i<T;++i) print(ans[i]),putchar(10);
return 0;
}
#线段树分治,线性基,并查集#CF938G Shortest Path Queries的更多相关文章
- $CF938G\ Shortest\ Path\ Queries$ 线段树分治+线性基
正解:线段树分治+线性基 解题报告: 传送门$QwQ$ 考虑如果只有操作3,就这题嘛$QwQ$ 欧克然后现在考虑加上了操作一操作二 于是就线段树分治鸭 首先线段树叶子节点是询问嘛这个不用说$QwQ$. ...
- BZOJ.4184.shallot(线段树分治 线性基)
BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ...
- Codeforces 938G 线段树分治 线性基 可撤销并查集
Codeforces 938G Shortest Path Queries 一张连通图,三种操作 1.给x和y之间加上边权为d的边,保证不会产生重边 2.删除x和y之间的边,保证此边之前存在 3.询问 ...
- LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset
题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ...
- 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)
Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ...
- 【线段树分治 线性基】luoguP3733 [HAOI2017]八纵八横
不知道为什么bzoj没有HAOI2017 题目描述 Anihc国有n个城市,这n个城市从1~n编号,1号城市为首都.城市间初始时有m条高速公路,每条高速公路都有一个非负整数的经济影响因子,每条高速公路 ...
- BZOJ4184:shallot(线段树分治,线性基)
Description 小苗去市场上买了一捆小葱苗,她突然一时兴起,于是她在每颗小葱苗上写上一个数字,然后把小葱叫过来玩游戏. 每个时刻她会给小葱一颗小葱苗或者是从小葱手里拿走一颗小葱苗,并且 让小葱 ...
- bzoj 4184 shallot——线段树分治+线性基
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4184 本来想了可持久化trie,不过空间是 nlogn (出一个节点的时候把 tot 复原就 ...
- bzoj 4184: shallot (线段树维护线性基)
题面 \(solution:\) 这一题绝对算的上是一道经典的例题,它向我们诠释了一种新的线段树维护方式(神犇可以跳过了).像这一类需要加入又需要维护删除的问题,我们曾经是遇到过的像莫对,线段树... ...
- Wanafly 挑战赛 14 E 无效位置 (线性基+并查集)
Wanafly 挑战赛 14 E 无效位置 (线性基+并查集) 传送门:https://ac.nowcoder.com/acm/contest/81/#question 题意: n个数,m次操作 一个 ...
随机推荐
- 修改centos7虚拟机的用户密码
在忘记原密码无法登录桌面的情况下,修改centos7的用户密码 非常规启动,进入编辑启动菜单 在启动GRUB菜单中选择编辑选项,按键e进入编辑; 找到linux16开头的一行,在该行中寻找ro的所在地 ...
- Golang条件编译介绍
相信熟悉 Golang 的小伙伴不少都知道 条件编译 这个事,最近项目中也可能会用到这个东西.所以特意重新学习下,记录下学习的过程.这样用的时候记不住了,还可以直接过来看自己的笔记. 文章很多内容来源 ...
- You can't specify target table for update in FROM clause
mysql中You can't specify target table for update in FROM clause错误的意思是说,不能先select出同一表中的某些值,再update这个表( ...
- linux复习基础命令
Linux基础命令 学习目标 了解vm备份的两种方式 了解快照和克隆的区别 了解linux系统文件 掌握基础命令 指定vmtools的作用 1 vm两种备份方式 为什么要进行备份 保证centos操作 ...
- 2、mysql存储引擎
存储引擎 1 存储引擎概述 和大多数的数据库不同, MySQL中有一个存储引擎的概念, 针对不同的存储需求可以选择最优的存储引擎. 存储引擎就是存储数据,建立索引,更新查询数据等等技术的实现方式 .存 ...
- 开源好用的所见即所得(WYSIWYG)编辑器:Editor.js
@ 目录 特点 基于区块 干净的数据 界面与交互 插件 标题和文本 图片 列表 Todo 表格 使用 安装 创建编辑器实例 配置工具 本地化 自定义样式 今天介绍一个开源好用的Web所见即所得(WYS ...
- 摆脱鼠标系列 - vscode - ctrl+up 光标上移动4行 ctrl+down 光标下移4行
为什么 摆脱鼠标系列 - vscode - ctrl+up 光标上移动4行 之前滚动屏幕总是用鼠标,现在改为 ctrl + 上箭头或下箭头 实现起来稍微有些麻烦 实现 需要安装 macros 插件 这 ...
- Navicat 通过 Http通道 连接远程 Mysql
https://jingyan.baidu.com/article/3d69c551aa54dff0cf02d7a0.html 注意本机ip填写 localhost
- Dreamweaver基础教程:系列介绍
目录 前言 Dreamweaver 软件介绍 软件安装 学习支持 相关资料 前言 我一直对前端的一些技术比较感兴趣,之前有用过GitHub上的开源项目部署了自己的导航网站猿导航,但并没有系统的去深入学 ...
- CRC常用参数模型及C#代码实现
目录 参数模型 算法实现 CRC-32 CRC-32/MPEG-2 表生成算法 参考资料 本文源码 参数模型 CRC即循环冗余校验码(Cyclic Redundancy Check):是数据通信领域中 ...