BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图
题意:加入边,删除边,查询当前图是否为二分图
本来想练lct,然后发现了线段树分治的做法,感觉好厉害。
lct做法的核心就是维护删除时间的最大生成树
首先口胡一个分块做法,和hnoi2016第一题类似的偏序关系,一样做。
线段树分治
数据结构题中如果使用对时间cdq分治,要求每个操作独立,不能很好的处理撤销(删除)操作。
采取线段树区间标记的思想
对于一个操作,它的存在时间是\([l,r]\)
我们模仿线段树打标记的过程进行分治,\(cdq(l,r,S)\)表示当前处理时间\([l,r]\),操作集合为\(S\)
如果区间就是当前区间,那么进行操作
否则继续递归
对于本题,用启发式合并 不路径压缩的并查集实现加边和撤销
越卡常越慢是smg
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long ll;
const int N=2e5+5;
inline int read(){
char c=getchar(); int x=0,f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
}
int n, m, T, u, v, l, r;
struct edge {
int u, v, l, r;
bool operator <(const edge &a) const {return l == a.l ? r < a.r : l < a.l;}
};
typedef vector<edge> meow;
meow a;
int top;
namespace ufs {
struct node {int fa, val, size;} t[N];
struct info {int x, y; node a, b;} st[N];
inline void init() {for(int i=1; i<=n; i++) t[i] = (node){i, 0, 1};}
inline int find(int x) {while(t[x].fa != x) x = t[x].fa; return x;}
inline int dis(int x) {
int ans=0;
while(t[x].fa != x) ans ^= t[x].val, x = t[x].fa;
return ans;
}
inline void link(int x, int y) {
int val = dis(x) ^ dis(y) ^ 1;
x = find(x); y = find(y);
st[++top] = (info) {x, y, t[x], t[y]};
if(t[x].size > t[y].size) swap(x, y);
t[x].fa = y; t[x].val = val; t[y].size += t[x].size;
}
inline void recov(int bot) {
while(top != bot) {
info &now = st[top--];
t[now.x] = now.a; t[now.y] = now.b;
}
}
} using namespace ufs;
void cdq(int l, int r, meow &a) {
int mid = (l+r)>>1, bot = top;
meow b, c;
for(int i=0; i<(int)a.size(); i++) {
edge &now = a[i];
int x = now.u, y = now.v;
if(now.l == l && now.r == r) {
int p = find(x), q = find(y);
if(p == q) {
int val = dis(x) ^ dis(y);
if(val == 0) {
for(int i=l; i<=r; i++) puts("No");
recov(bot); return;
}
} else link(x, y);
}
else if(now.r <= mid) b.push_back(now);
else if(mid < now.l) c.push_back(now);
else b.push_back( (edge){now.u, now.v, now.l, mid} ), c.push_back( (edge){now.u, now.v, mid+1, now.r} );
}
if(l == r) puts("Yes");
else cdq(l, mid, b), cdq(mid+1, r, c);
recov(bot);
}
int main() {
//freopen("in", "r", stdin);
n=read(); m=read(); T=read();
for(int i=1; i<=m; i++) {
u=read(), v=read(), l=read()+1, r=read();
if(l > r) continue;
a.push_back((edge){u, v, l, r});
}
init();
cdq(1, T, a);
}
BZOJ 4025: 二分图 [线段树CDQ分治 并查集]的更多相关文章
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- bzoj 4025 二分图——线段树分治+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...
- 【openjudge】C15C Rabbit's Festival CDQ分治+并查集
题目链接:http://poj.openjudge.cn/practice/C15C/ 题意:n 点 m 边 k 天.每条边在某一天会消失(仅仅那一天消失).问每一天有多少对点可以相互到达. 解法:开 ...
- BZOJ 3939 [Usaco2015 Feb]Cow Hopscotch ——线段树 CDQ分治
显然dp[i][j]=ps[i-1][j-1]-sigma(dp[k<i][l<j],a[i][j]=a[k][l]) 考虑对于每一种颜色都开一颗区间线段树,但是空间不够. 所以我们可以动 ...
- COGS 577 蝗灾 线段树+CDQ分治
第一次写cdq分治 感谢hhd<y 这20亿对CP的指导(逃) 其实 就是 递归看左半部分对右半部分的贡献 (树状数组写挂了--临时改的线段树[大写的尴尬]) //By SiriusRen ...
- hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)
题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...
- BZOJ 2333 棘手的操作(离线+线段树+带权并查集)
这题搞了我一天啊...拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊.我的线段树要开8倍才能过啊... 首先可以发现除了那个加边操作,其他的操作有点像线段树啊.如果我们把每次询问的联通块都放在一 ...
- BZOJ 2733 线段树的合并 并查集
思路: 1.线段树合并(nlogn的) 2.splay+启发式合并 线段树合并比较好写 我手懒 //By SiriusRen #include <cstdio> #include < ...
- BZOJ 2733 [HNOI2012]永无乡 (权值线段树启发式合并+并查集)
题意: n<=1e5的图里,在线连边.查询某连通块第k大 思路: 练习线段树合并的好题,因为依然记得上一次启发式合并trie的时候内存爆炸的恐怖,所以这次还是用了动态开点.回收 听说启发式合并s ...
随机推荐
- Spring学习日志之Spring MVC启动配置
对DispatcherServlet进行配置 Spring MVC的配置实际上就是对DispatcherServlet的配置 public class DispatcherServletConfig ...
- MFC中菜单的命令响应顺序
响应只可以由Doc,View,MainFrame以及APP四个类完成. 响应顺序是: 点击某菜单项,框架类最先接到菜单命令消息. 框架类把接收到得这个消息交给它的子窗口,即视图类. 视图类根据命令消息 ...
- JavaScript变量声明与提升
一直以来对变量提升都是比较模糊的,今天特地看了一下这个知识点,总结一下. 1.举个最简单的例子来说一下什么是变量提升吧. function foo(){ console.log(x); // unde ...
- C# 小笔记
1,Using using (var ws = new WebSocket ("ws://dragonsnest.far/Laputa")) { ws.OnMessage += ( ...
- 将js进行到底:node学习笔记2
node重要API之FS--CLI编程初体验 所谓的"fs"就是file system! 当下几乎任何一门编程语言都会提供对文件系统读写的API,比如c语言的open()函数. 而 ...
- CCF系列之最大的矩形(201312-3)
试题名称: 最大的矩形 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 在横轴上放了n个相邻的矩形,每个矩形的宽度是1,而第i(1 ≤ i ≤ n)个矩形的高度是hi.这n个矩 ...
- ASP.net core 2.0.0 中 asp.net identity 2.0.0 的基本使用(一)—修改数据库连接
开发环境:vs2017 版本:15.3.5 项目环境:.net framework 4.6.1 模板asp.net core 2.0 Web应用程序(模型视图控制器) 身份验证:个人用户账号 ...
- webpack 基本打包方法
webpack的打包基本配置文件webpack.config.js 可以在webpack.config.js里面写好配置:比如前章节所总结的四大核心 |-- add.js // 定义一个普通加法函数 ...
- Azure Powershell使用已有特殊化非托管磁盘创建ARM虚拟机
生成已有特殊化非托管磁盘的方法主要有如下两种: 1.使用StorageExplorer存储管理工具,复制特殊化磁盘到一个新的容器下 2.New Portal中删除虚拟机,默认vhd文件会保留在存储账号 ...
- 转-HTTP POST GET SOAP本质区别详解
原文链接:HTTP POST GET SOAP本质区别详解 一 原理区别 一般在浏览器中输入网址访问资源都是通过GET方式:在FORM提交中,可以通过Method指定提交方式为GET或者POST,默认 ...