Codeforces 938G 线段树分治 线性基 可撤销并查集
Codeforces 938G Shortest Path Queries
一张连通图,三种操作
1.给x和y之间加上边权为d的边,保证不会产生重边
2.删除x和y之间的边,保证此边之前存在
3.询问x到y的路径异或最小值
保证图在任意时刻连通
首先连通图路径异或相当于从x到y的任意一条路径再异或上若干个环得到的,只要在dfs过程中把非树边成的环丢到线性基里就好了,其他环一定可以通过这些环异或组合出来
有加边删边操作怎么做呢?线段树时间分治!注意到不能保证在线段树的任意一个节点图是连通的,需要用可撤销并查集来维护,总复杂度\(O(q\log(n)\log(q))\)
tips:其实线性基因为一次插入只有一个赋值操作也可以用同样的方式撤销,不一定要每次都复制一遍下传
//segment tree divide and conquer
//linear base, dsu(rollback)
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
struct Linear_Base {
	int a[30];
	Linear_Base() {memset(a, 0, sizeof(a));}
	void insert(int val) {
		for(int i = 29; ~i; --i) {
			if((val >> i) & 1) {
				if(a[i] == 0) {
					a[i] = val;
					return;
				}
				val ^= a[i];
			}
		}
	}
	int query(int val) {
		for(int i = 29; ~i; --i)
			val = min(val, val ^ a[i]);
		return val;
	}
};
pair<int*, int> save[N * 10];
int top;
void change(int &address, int val) {
	save[top++] = make_pair(&address, address);
	address = val;
}
void rollback(int st) {
	while(st != top) {
		top--;
		*save[top].first = save[top].second;
	}
}
struct edge {
	int x, y, d;
	edge() {x = y = d = 0;}
	edge(int _x, int _y, int _d) : x(_x), y (_y), d(_d) {}
};
struct que {
	int x, y, id;
	que() {x = y = id = 0;}
	que(int _x, int _y, int _id) : x(_x), y (_y), id(_id) {}
};
int ans[N], tot;
vector<edge> G[N << 2];
vector<que> Q[N << 2]; 
int dsu[N], size[N], dis[N];
int find(int x) {
	return x == dsu[x] ? x : find(dsu[x]);
}
int get_dist(int x) {
	return x == dsu[x] ? 0 : dis[x] ^ get_dist(dsu[x]);
}
int unite(int x, int y, int d) {
	d ^= get_dist(x);
	d ^= get_dist(y);
	x = find(x);
	y = find(y);
	if(x == y)
		return 0;
	if(size[x] < size[y]) swap(x, y);
	change(size[x], size[x] + size[y]);
	change(dsu[y], x);
	change(dis[y], d);
	return 1;
}
void update(int rt, int l, int r, int L, int R, const edge &x) {
	if(L <= l && r <= R) {G[rt].push_back(x); return;}
	int mid = l + r >> 1;
	if(L <= mid) update(rt << 1, l, mid, L, R, x);
	if(R > mid) update(rt << 1 | 1, mid + 1, r, L, R, x);
}
void add_query(int rt, int l, int r, int pos, const que &x) {
	if(l == r) {Q[rt].push_back(x); return;}
	int mid = l + r >> 1;
	if(pos <= mid) add_query(rt << 1, l, mid, pos, x);
	else add_query(rt << 1 | 1, mid + 1, r, pos, x);
}
void dfs(int rt, int l, int r, Linear_Base Base) {
	int st = top;
	for(auto e : G[rt]) {
		if(!unite(e.x, e.y, e.d)) {
			Base.insert(get_dist(e.x) ^ get_dist(e.y) ^ e.d);
		}
	}
	if(l == r) {
		for(auto q : Q[rt])
			ans[q.id] = Base.query(get_dist(q.x) ^ get_dist(q.y));
	}
	else {
		int mid = l + r >> 1;
		dfs(rt << 1, l, mid, Base);
		dfs(rt << 1 | 1, mid + 1, r, Base);
	}
	rollback(st);
}
int n, m, q, op, x, y, d;
map<pair<int, int>, pair<int, int>> st;
int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; ++i) dsu[i] = i, size[i] = 1, dis[i] = 0;
	for(int i = 1; i <= m; ++i) {
		scanf("%d%d%d", &x, &y, &d);
		st[make_pair(x, y)] = make_pair(1, d);
	}
	scanf("%d", &q);
	for(int i = 1; i <= q; ++i) {
		scanf("%d%d%d", &op, &x, &y);
		if(op == 1) {
			scanf("%d", &d);
			st[make_pair(x, y)] = make_pair(i, d);
		}
		else if(op == 2) {
			update(1, 1, q, st[make_pair(x, y)].first, i, edge(x, y, st[make_pair(x, y)].second));
			st.erase(make_pair(x, y));
		}
		else {
			add_query(1, 1, q, i, que(x, y, ++tot));
		}
	}
	for(auto e: st) {
		update(1, 1, q, e.second.first, q, edge(e.first.first, e.first.second, e.second.second));
	}
	dfs(1, 1, q, Linear_Base());
	for(int i = 1; i <= tot; ++i) {
		printf("%d\n", ans[i]);
	}
	return 0;
}
Codeforces 938G 线段树分治 线性基 可撤销并查集的更多相关文章
- BZOJ.4184.shallot(线段树分治 线性基)
		BZOJ 裸的线段树分治+线性基,就是跑的巨慢_(:з」∠)_ . 不知道他们都写的什么=-= //41652kb 11920ms #include <map> #include < ... 
- $CF938G\ Shortest\ Path\ Queries$ 线段树分治+线性基
		正解:线段树分治+线性基 解题报告: 传送门$QwQ$ 考虑如果只有操作3,就这题嘛$QwQ$ 欧克然后现在考虑加上了操作一操作二 于是就线段树分治鸭 首先线段树叶子节点是询问嘛这个不用说$QwQ$. ... 
- 【luogu3733】【HAOI2017】 八纵八横 (线段树分治+线性基)
		Descroption 原题链接 给你一个\(n\)个点的图,有重边有自环保证连通,最开始有\(m\)条固定的边,要求你支持加边删边改边(均不涉及最初的\(m\)条边),每一次操作都求出图中经过\(1 ... 
- LOJ 2312(洛谷 3733) 「HAOI2017」八纵八横——线段树分治+线性基+bitset
		题目:https://loj.ac/problem/2312 https://www.luogu.org/problemnew/show/P3733 原本以为要线段树分治+LCT,查了查发现环上的值直 ... 
- 【线段树分治 线性基】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:\) 这一题绝对算的上是一道经典的例题,它向我们诠释了一种新的线段树维护方式(神犇可以跳过了).像这一类需要加入又需要维护删除的问题,我们曾经是遇到过的像莫对,线段树... ... 
- BZOJ4025: 二分图【线段树分治】【带撤销的并查集】
		Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ... 
随机推荐
- CSIC_716_20191118【常用模块的用法 Json、pickle、collections、openpyxl】
			序列化模块 序列化:将python或其他语言中的数据类型,转变成字符串类型. python中的八大数据类型回顾:int float str list tuple dict set bool 反序列化: ... 
- Redhat镜像-RHEL-官方镜像下载大全
			原网站内容链接:https://pan.baidu.com/s/12XYXh#list/path=%2F 已经存在自己的云盘上了 
- Excel-根据分隔符将一个单元格的内容分发到多个单元格
			A1 1:2:3:4:5:6:7::::10 现在想将A1根据";"进行分离,再讲分离出来的一个值填到一个单元格中 =TRIM(MID(SUBSTITUTE($A$12," ... 
- Android App上架流程
			想要把APP上架到应用市场都要先注册开发者账号才可以.这里的方法包括注册帐号和后期上架及一些需要注意的问题.注意:首次提交应用绝对不能随便删除,否则后面再提交会显示应用APP冲突,会要求走应用认领流程 ... 
- hdu多校第二场 1005 (hdu6595) Everything Is Generated In Equal Probability
			题意: 给定一个N,随机从[1,N]里产生一个n,然后随机产生一个n个数的全排列,求出n的逆序数对的数量,加到cnt里,然后随机地取出这个全排列中的一个非连续子序列(注意这个子序列可以是原序列),再求 ... 
- mongodb操作指令(一):数据库,集合,文档
			数据库 查看所有数据库 show dbs 查看当前数据库 db 创建使用数据库use runoob 删除数据库 db.dropDatabase() 集合 创建集合db.createCollection ... 
- spark jdk8 单词统计示例
			在github上有spark-java8 实例地址: https://github.com/ypriverol/spark-java8 https://github.com/ihr/java8-spa ... 
- 任意文件读取漏洞常用payload合集
			直接整理到github上了,https://github.com/tdifg/payloads 其他payload以后不定期更新 
- 【珍惜时间】iReport
			项目很点意思,感觉很高超的样子 先放下项目的github地址:https://github.com/tctangyanan/iReport 感谢各位伟大的程序员无私的分享自己的技术 老规矩,我们会运行 ... 
- 2016.9.24初中部上午NOIP普及组比赛总结
			2016.9.24初中部上午NOIP普及组比赛总结 2016.09.24[初中部 NOIP普及组 ]模拟赛 其实这次我没比赛,早上去参加亲子活动去了. 不过在下午我做完了所有的题,感觉还好. 进度 现 ... 
