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分治 并查集]的更多相关文章

  1. [BZOJ 4025]二分图(线段树分治+带边权并查集)

    [BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...

  2. bzoj 4025 二分图——线段树分治+LCT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...

  3. 【openjudge】C15C Rabbit's Festival CDQ分治+并查集

    题目链接:http://poj.openjudge.cn/practice/C15C/ 题意:n 点 m 边 k 天.每条边在某一天会消失(仅仅那一天消失).问每一天有多少对点可以相互到达. 解法:开 ...

  4. 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]) 考虑对于每一种颜色都开一颗区间线段树,但是空间不够. 所以我们可以动 ...

  5. COGS 577 蝗灾 线段树+CDQ分治

    第一次写cdq分治 感谢hhd&lty 这20亿对CP的指导(逃) 其实 就是 递归看左半部分对右半部分的贡献 (树状数组写挂了--临时改的线段树[大写的尴尬]) //By SiriusRen ...

  6. hdu_5354_Bipartite Graph(cdq分治+并查集判二分图)

    题目链接:hdu_5354_Bipartite Graph 题意: 给你一个由无向边连接的图,问对于每一个点来说,如果删除这个点,剩下的点能不能构成一个二分图. 题解: 如果每次排除一个点然后去DFS ...

  7. BZOJ 2333 棘手的操作(离线+线段树+带权并查集)

    这题搞了我一天啊...拍不出错原来是因为极限数据就RE了啊,竟然返回WA啊.我的线段树要开8倍才能过啊... 首先可以发现除了那个加边操作,其他的操作有点像线段树啊.如果我们把每次询问的联通块都放在一 ...

  8. BZOJ 2733 线段树的合并 并查集

    思路: 1.线段树合并(nlogn的) 2.splay+启发式合并 线段树合并比较好写 我手懒 //By SiriusRen #include <cstdio> #include < ...

  9. BZOJ 2733 [HNOI2012]永无乡 (权值线段树启发式合并+并查集)

    题意: n<=1e5的图里,在线连边.查询某连通块第k大 思路: 练习线段树合并的好题,因为依然记得上一次启发式合并trie的时候内存爆炸的恐怖,所以这次还是用了动态开点.回收 听说启发式合并s ...

随机推荐

  1. c语言中的堆、栈和内存映射

    Code Area(代码区):程序代码指令.常量字符串,只可读. Static Area(静态区):存放全局变量/常量.静态变量/常量. 该区域的大小在程序一加载进内存的时候就已固定,但是静态变量的值 ...

  2. 初步了解关于js跨域问题-jsonp

    js跨域问题是指在js在不同的域中进行数据传输或者数据通信,比如通过ajax向不同的域请求数据(说到ajax,不可避免的就会遇到两个问题:一是ajax是如何传递数据的?二是ajax是如何实现跨域的?) ...

  3. A glance at endpoint security

    Last year hackers stole millions from Taiwan First Commercial bank's ATMs without using a card. This ...

  4. 关于HTTP请求出现 405状态码 not allowed的解决办法

    最近学爬虫.发现httppost请求目标网站会出现405 状态码,原因为 Apache.IIS.Nginx等绝大多数web服务器,都不允许静态文件响应POST请求 所以将post请求改为get请求即可

  5. Vuthink正确安装过程

    1.      下载项目vuethink,本例将项目放置website文件下. 2.      后台搭建 本地建站–>以phpstudy为例 1)      新建站点域名 <Virtual ...

  6. 随手小代码——《Python编程 从入门到实践》项目1:外星人入侵

    =================================版权声明================================= 版权声明:原创文章 禁止转载  请通过右侧公告中的“联系邮 ...

  7. ::在c++中什么意思

    (1)表示“域操作符” 例:声明了一个类A,类A里声明了一个成员函数void f(),但没有在类的声明里给出f的定义,那么在类外定义f时, 就要写成void A::f(),表示这个f()函数是类A的成 ...

  8. plist涉及到沙盒的一个问题

    http://blog.csdn.net/wowxavi1/article/details/8557271

  9. 经典CSS坑:如何完美实现垂直水平居中?

    经典CSS坑:如何完美实现垂直水平居中? 踩了各种坑之后总结出的方法,开门见山,直接上代码和效果图.希望对读者有所帮助,后续如果有更好的方法,我也会持续更新 第一种方法:transform(个人认为最 ...

  10. 用IDEA/WebStrom 提交本地项目到Git/码云等

    以码云为例: 在码云上创建新的项目. webstrom/idea 打开本地项目