首先只有询问的话就是个WC的题,线性基+生成树搞一搞就行。

进一步,考虑如果修改操作只有加边怎么做。

好像也没有什么变化,只不过需要在线地往线性基里插入东西而已。

删边呢?

注意到线性基这个玩意是不支持删除操作的。

对于这种不好删除的的东西有种不错的解决方法,就是线段树分治。

把每个操作劈成logn个区间以后来搞一下。

按照线段树分治的套路,通过遍历整棵线段树来获得答案。

发现需要一个可以动态维护支持加/删边的生成树的东西。

能做到这个的无非就两个数据结构,按秩合并的并查集和LCT。

这里使用按秩合并的并查集。

注意:

这里之所以利用线段树分治的原因是,使用线段树结构可以在每个节点都维护出对应的线性基。

儿子的线性基可以由线段树上的父亲的线性基加上自身节点内的操作来得到,由于线性基很小,可以快速下传,因此可以这么搞。

剩下的就是码码码了

#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<map>
#include<vector>
#include<cstdlib>
#include<algorithm>
#define N 440000
#define L 1000000
#define M 6600000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline int read()
{
char ch=0;
int x=0,flag=1;
while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*flag;
}
struct link{int x,y,z;};
bool operator<(link a,link b){if(a.x!=b.x)return a.x<b.x;return a.y<b.y;}
map<link,int>S;
map<link,int>::iterator it;
int n,m,qnum,now,cnt,tot,ans[N];
struct ques{int x,y,id;}q[N];
struct node{link s;int l,r;}p[N*2];
//find-union-set
int top,f[N],v[N],sz[N],sk[M];
int find(int x){if(x!=f[x])return find(f[x]);else return f[x];}
int value(int x){if(x!=f[x])return value(f[x])^v[x];else return 0;}
bool merge(link s)
{
int a=s.x,b=s.y,x=find(a),y=find(b),z=s.z;
if(x==y)return false;
if(sz[x]>sz[y])swap(x,y),swap(a,b);
v[x]=value(a)^value(b)^z;
f[x]=y;sz[y]+=sz[x];sk[++top]=x;
return true;
}
void erase()
{
int x=sk[top--];
sz[f[x]]-=sz[x];f[x]=x;v[x]=0;
}
//linear basis
struct pot
{
int s[33];
void insert(int x)
{
for(int i=31;i>=0;i--)if(1<<i&x)
{
if(!s[i]){s[i]=x;break;}
else x^=s[i];
}
}
int query(int x)
{
for(int i=31;i>=0;i--)if(1<<i&x)x^=s[i];
return x;
}
}sp[200];
//Segment_Tree
#define lson o<<1
#define rson o<<1|1
#define mid ((l+r)>>1)
vector<link>V[N*4];
void optset(int o,int l,int r,int ql,int qr,link s)
{
if(ql<=l&&r<=qr){V[o].push_back(s);return;}
if(ql<=mid)optset(lson,l,mid,ql,qr,s);
if(qr>mid)optset(rson,mid+1,r,ql,qr,s);
}
void solve(int o,int l,int r,int t)
{
if(l>r)return;
int times=0,len=V[o].size();
for(int i=0;i<len;i++)
if(merge(V[o][i]))times++;
else sp[t].insert(value(V[o][i].x)^value(V[o][i].y)^V[o][i].z);
if(l==r)
{
while(now<tot&&q[now+1].id==l)
{
now++;
ans[q[now].id]=sp[t].query(value(q[now].x)^value(q[now].y));
}
}
else
{
for(int i=31;i>=0;i--)sp[t+1].s[i]=sp[t].s[i];solve(lson,l,mid,t+1);
for(int i=31;i>=0;i--)sp[t+1].s[i]=sp[t].s[i];solve(rson,mid+1,r,t+1);
}
for(int i=0;i<times;i++)erase();
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;i++)
{
link o;
o.x=read();o.y=read();o.z=read();
if(o.x>o.y)swap(o.x,o.y);
S.insert(pair<link,int>(o,0));
}
qnum=read();
for(int i=1;i<=qnum;i++)
{
int flag=read();
if(flag==1)
{
link o;
o.x=read();o.y=read();o.z=read();
if(o.x>o.y)swap(o.x,o.y);
S.insert(pair<link,int>(o,i));
}
if(flag==2)
{
link o;
o.x=read();o.y=read();
it=S.find(o);
p[++cnt]=(node){it->first,it->second,i};
S.erase(it);
}
if(flag==3)
{
q[++tot].id=i;q[tot].x=read();q[tot].y=read();
if(q[tot].x>q[tot].y)swap(q[tot].x,q[tot].y);
}
}
for(it=S.begin();it!=S.end();it++)p[++cnt]=(node){it->first,it->second,m};
for(int i=1;i<=cnt;i++)optset(1,0,qnum,p[i].l,p[i].r,p[i].s);
for(int i=1;i<=n;i++)f[i]=i,v[i]=0,sz[i]=1;
solve(1,0,m,1);
for(int i=1;i<=tot;i++)printf("%d\n",ans[q[i].id]);
return 0;
}

CF938G Shortest Path Queries的更多相关文章

  1. CF938G Shortest Path Queries 和 CF576E Painting Edges

    这两道都用到了线段树分治和按秩合并可撤销并查集. Shortest Path Queries 给出一个连通带权无向图,边有边权,要求支持 q 个操作: x y d 在原图中加入一条 x 到 y 权值为 ...

  2. $CF938G\ Shortest\ Path\ Queries$ 线段树分治+线性基

    正解:线段树分治+线性基 解题报告: 传送门$QwQ$ 考虑如果只有操作3,就这题嘛$QwQ$ 欧克然后现在考虑加上了操作一操作二 于是就线段树分治鸭 首先线段树叶子节点是询问嘛这个不用说$QwQ$. ...

  3. 【CF938G】Shortest Path Queries(线段树分治,并查集,线性基)

    [CF938G]Shortest Path Queries(线段树分治,并查集,线性基) 题面 CF 洛谷 题解 吼题啊. 对于每个边,我们用一个\(map\)维护它出现的时间, 发现询问单点,边的出 ...

  4. 题解 CF938G 【Shortest Path Queries】

    题目让我们维护一个连通无向图,边有边权,支持加边删边和询问从\(x\)到\(y\)的异或最短路. 考虑到有删边这样的撤销操作,那么用线段树分治来实现,用线段树来维护询问的时间轴. 将每一条边的出现时间 ...

  5. Codeforces 938G Shortest Path Queries [分治,线性基,并查集]

    洛谷 Codeforces 分治的题目,或者说分治的思想,是非常灵活多变的. 所以对我这种智商低的选手特别不友好 脑子不好使怎么办?多做题吧-- 前置知识 线性基是你必须会的,不然这题不可做. 推荐再 ...

  6. CF 938G Shortest Path Queries

    又到了喜闻乐见的写博客清醒时间了233,今天做的依然是线段树分治 这题算是经典应用了吧,假的动态图(可离线)问题 首先不难想到对于询问的时间进行线段树分治,这样就可以把每一条边出现的时间区间扔进线段树 ...

  7. Shortest Path(思维,dfs)

    Shortest Path  Accepts: 40  Submissions: 610  Time Limit: 4000/2000 MS (Java/Others)  Memory Limit: ...

  8. Shortest Path

    Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

  9. 74(2B)Shortest Path (hdu 5636) (Floyd)

    Shortest Path Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)T ...

随机推荐

  1. Linux基础命令---e2image

    e2image e2Image程序将位于设备上的ext2.ext3或ext4文件系统元数据保存到由图像文件指定的文件中.通过对这些程序使用-i选项,image文件可以由dupe2fs和调试器来检查.这 ...

  2. 阿里云云主机swap功能设置实战案例

    阿里云云主机swap功能设置实战案例 阿里云提供的云服务器(Elastic Compute Service,简称 ECS),是云主机的一种,当前采用的虚拟化驱动是Xen(这一点可以通过bios ven ...

  3. seo标题关键字描述字数限制Title,keywords,description长度最长多长 ?

    seo标题关键字描述字数限制 seo优化各个搜索引擎收录Title,keywords,description长度最长多长 ?SEO网站优化中Title标签的作用为重中之重,好的Title也就成功了一半 ...

  4. MySQL用sql复制表数据到新表的方法

    用sqlyog无法直接复制出一个不同表名的表来,只能copy到其他库上同名的表. 在MySQL数据库中,应该如何用sql将表数据复制到新表中呢? 本人通过试验测试成功了,而且相当简单易懂,速度也非常快 ...

  5. 业余时间正在开发一个REACT小视频站点

    业余时间正在开发一个REACT小视频站点,数据接口来源于吐槽弹幕网(C站),供C站用户移动端的观看.因现存在移动网络屏蔽C站的关系,最好使用非移动网络进行观看.否则会比较卡,影响用户体验. 站点测试入 ...

  6. 在python3下使用OpenCV 显示图像

    在Python3下用使用OpenCV比在C,C++里开发不止快捷一点点, 原型开发的时候蛮有用. 这里用的OpenCV 加载图片, 用的imshow画图 # -*- coding: utf-8 -*- ...

  7. JavaScript甜点(1)

    甜点1:什么是脚本语言? 脚本语言是由传统编程语言简化而来的,它与传统的编程语言既有很多相似之处,又有很多的不同之处.脚本语言的最显著的特点是:首先它不需要编译成二进制,以文本的形式存在:其次就是脚本 ...

  8. Intel RDT

    首先 spec, 从671页看起 https://software.intel.com/sites/default/files/managed/a4/60/325384-sdm-vol-3abcd.p ...

  9. script 加载顺序问题的延展研究

    今天群里有人问为什么会出现脚本的加载顺序与定义脚本顺序不一致的问题,这个问题引起了我的好奇,经过一番调研,有了这篇文章. 这是一个伪命题吗? 首先,W3C 推荐 script 脚本应该被立即加载和执行 ...

  10. UVA 11806 Cheerleaders (容斥原理

    1.题意描述 本题大致意思是讲:给定一个广场,把它分为M行N列的正方形小框.现在给定有K个拉拉队员,每一个拉拉队员需要站在小框内进行表演.但是表演过程中有如下要求: (1)每一个小框只能站立一个拉拉队 ...