【BZOJ4025】二分图

Description

神犇有一个n个节点的图。因为神犇是神犇,所以在T时间内一些边会出现后消失。神犇要求出每一时间段内这个图是否是二分图。这么简单的问题神犇当然会做了,于是他想考考你。

Input

输入数据的第一行是三个整数n,m,T。
第2行到第m+1行,每行4个整数u,v,start,end。第i+1行的四个整数表示第i条边连接u,v两个点,这条边在start时刻出现,在第end时刻消失。

Output

输出包含T行。在第i行中,如果第i时间段内这个图是二分图,那么输出“Yes”,否则输出“No”,不含引号。

Sample Input

3 3 3
1 2 0 2
2 3 0 3
1 3 1 2

Sample Output

Yes
No
Yes

HINT

样例说明:
0时刻,出现两条边1-2和2-3。
第1时间段内,这个图是二分图,输出Yes。
1时刻,出现一条边1-3。
第2时间段内,这个图不是二分图,输出No。
2时刻,1-2和1-3两条边消失。
第3时间段内,只有一条边2-3,这个图是二分图,输出Yes。
数据范围:
n<=100000,m<=200000,T<=100000,1<=u,v<=n,0<=start<=end<=T。

题解:感觉cdq分治过于高端,LCT比较好想~

我们希望这样一个集合(本质是数组),保存的是当前时刻,所有加入之后会形成奇环的非树边。如果当前时刻集合中有元素,则不是一个二分图。那么删边的时候如何处理呢?如果我们删的是一条树边,那么假如集合中存在一条覆盖这条树边的非树边,那么这条非树边就会变成新的树边。这样的情况很难处理,所以我们希望保证:所有已经进入集合的非树边都不会从集合中出来再次成为树边,即,我们要维护的是关于删除时间的最大生成树。可以用LCT搞定。

然后就没啦~我在link的时候手残连的是实边,居然也过了~

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn=500010;
int n,m,T,tot,sum;
int vis[maxn];
struct LCT
{
int ch[2],fa,v,sm,rev,siz;
}s[maxn];
struct edge
{
int pa,pb,t1,t2;
}p[maxn];
struct operate
{
int tim,op,org;
}q[maxn];
bool cmp(operate a,operate b)
{
return (a.tim==b.tim)?(a.op>b.op):(a.tim<b.tim);
}
bool isr(int x) {return s[s[x].fa].ch[0]!=x&&s[s[x].fa].ch[1]!=x;}
int MN(int a,int b)
{
return s[a].v<s[b].v?a:b;
}
void pushup(int x)
{
s[x].siz=s[s[x].ch[0]].siz+s[s[x].ch[1]].siz+1;
s[x].sm=MN(x,MN(s[s[x].ch[0]].sm,s[s[x].ch[1]].sm));
}
void pushdown(int x)
{
if(s[x].rev)
{
swap(s[x].ch[0],s[x].ch[1]);
if(s[x].ch[0]) s[s[x].ch[0]].rev^=1;
if(s[x].ch[1]) s[s[x].ch[1]].rev^=1;
s[x].rev=0;
}
}
void updata(int x)
{
if(!isr(x)) updata(s[x].fa);
pushdown(x);
}
void rotate(int x)
{
int y=s[x].fa,z=s[y].fa,d=(x==s[y].ch[1]);
if(!isr(y)) s[z].ch[y==s[z].ch[1]]=x;
s[x].fa=z,s[y].fa=x,s[y].ch[d]=s[x].ch[d^1];
if(s[x].ch[d^1]) s[s[x].ch[d^1]].fa=y;
s[x].ch[d^1]=y;
pushup(y),pushup(x);
}
void splay(int x)
{
updata(x);
while(!isr(x))
{
int y=s[x].fa,z=s[y].fa;
if(!isr(y))
{
if((x==s[y].ch[1])^(y==s[z].ch[1])) rotate(x);
else rotate(y);
}
rotate(x);
}
}
void access(int x)
{
for(int y=0;x;splay(x),s[x].ch[1]=y,pushup(x),y=x,x=s[x].fa);
}
void maker(int x)
{
access(x),splay(x),s[x].rev^=1;
}
void link(int x,int y) //x上
{
//printf("l %d %d\n",x,y);
access(x),splay(x),maker(y);
s[x].ch[1]=y,s[y].fa=x,pushup(x);
}
void cut(int x,int y)
{
//printf("c %d %d\n",x,y);
maker(x),access(y),splay(y);
s[y].ch[0]=s[x].fa=0,pushup(y);
}
int findr(int x)
{
access(x),splay(x);
while(s[x].ch[0]) x=s[x].ch[0];
return x;
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd(),m=rd(),T=rd();
int i,j,a,b,c,d;
for(i=0;i<=n;i++) s[i].v=1<<30;
for(i=1;i<=m;i++)
{
p[i].pa=rd(),p[i].pb=rd(),q[i].tim=p[i].t1=rd(),s[i+n].v=q[i+m].tim=p[i].t2=rd();
s[i+n].siz=1,s[i+n].sm=i+n;
q[i].org=q[i+m].org=i,q[i].op=1,q[i+m].op=0;
}
sort(q+1,q+2*m+1,cmp);
for(i=j=1;i<=T;i++)
{
for(;j<=2*m&&q[j].tim<i;j++)
{
a=p[q[j].org].pa,b=p[q[j].org].pb,c=q[j].org+n;
if(q[j].op)
{
if(findr(a)!=findr(b)) link(a,c),link(b,c);
else
{
maker(a),access(b),splay(b),d=s[b].sm;
if((s[b].siz+1)&2)
{
sum++;
if(s[d].v<s[c].v) cut(d,p[d-n].pa),cut(d,p[d-n].pb),link(a,c),link(b,c),vis[d]=1;
else vis[c]=1;
}
else
{
if(s[d].v<s[c].v) cut(d,p[d-n].pa),cut(d,p[d-n].pb),link(a,c),link(b,c),vis[d]=2;
else vis[c]=2;
}
}
}
else
{
if(!vis[c]) cut(c,a),cut(c,b);
if(vis[c]==1) sum--;
}
}
if(sum) printf("No\n");
else printf("Yes\n");
}
return 0;
}

【BZOJ4025】二分图 LCT的更多相关文章

  1. bzoj4025: 二分图 lct

    题意:带增删边的查询二分图 题解:因为二分图肯定带奇环,lct维护,每次要加入一条边之前判断会不会构成环,如果会就把最先会删除的边删掉,然后如果是奇环就打个标记,然后把奇环数++,删除的时候,把标记删 ...

  2. [BZOJ4025] 二分图 LCT/(线段树分治+并查集)

    4025: 二分图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2667  Solved: 989[Submit][Status][Discuss] ...

  3. bzoj4025 二分图 LCT + 最小生成树

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4025 题解 貌似这道题有一个非常简单的做法是线段树分治+并查集. 可是我是为了练 LCT 来做 ...

  4. BZOJ4025: 二分图(LCT)

    Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...

  5. [BZOJ4025]二分图(线段树分治,并查集)

    4025: 二分图 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2191  Solved: 800[Submit][Status][Discuss] ...

  6. [bzoj4025]二分图_LCT

    二分图 bzoj-4025 题目大意:给定一个n个节点的图,m条边,每条边有一个产生时间和一个删除时间,询问所有时间点是否是连通图. 注释:$1\le n\le 10^5$,$1\le m\le 2\ ...

  7. bzoj4025 二分图

    支持加边和删边的二分图判定,分治并查集水之(表示我的LCT还很不熟--仅仅停留在极其简单的模板水平). 由于是带权并查集,并且不能路径压缩,所以对权值(到父亲距离的奇偶性)的维护要注意一下. 有一个小 ...

  8. bzoj4025二分图(线段树分治 并查集)

    /* 思维难度几乎没有, 就是线段树分治check二分图 判断是否为二分图可以通过维护lct看看是否链接出奇环 然后发现不用lct, 并查集维护奇偶性即可 但是复杂度明明一样哈 */ #include ...

  9. BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并

    原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...

随机推荐

  1. spring mvc: 参数方法名称解析器(用参数来解析控制器下的方法)MultiActionController/ParameterMethodNameResolver/ControllerClassNameHandlerMapping

    spring mvc: 参数方法名称解析器(用参数来解析控制器下的方法)MultiActionController/ParameterMethodNameResolver/ControllerClas ...

  2. 关于hugepages 3.txt

    关于hugepages 3.txt --//有一段时间我一直强调安装oracle一定要配置hugepage,因为现在的服务器内存越来越大,如果还使用4K的页面表,如果内存表占用内存巨大, --//特别 ...

  3. 20165332 2017-2018-2《Java程序设计》课程总结

    20165332 2017-2018-2<Java程序设计>课程总结 一.每周作业及实验报告链接汇总 我期望的师生关系 学习基础和c语言基础调查 Linux安装及命令入门 第一周学习总结 ...

  4. C++(三十一) — 静态成员变量、静态成员函数

    1.静态成员变量 类的静态成员变量是,由该类的所以对象共同维护和使用的数据成员,每个类只有一个副本,是类数据成员的一种特例.采用 static 关键字声明. 目的:实现同一类中不同对象之间的数据共享. ...

  5. 关闭多个screen

    由于开了很多个screen同时工作,关闭是一个一个比较麻烦,写个命令在这以便日后想不起来时可以用到. 1.先看看有多少个screen    screen -ls |awk '/Socket/'|awk ...

  6. python爬虫之性能相关

    性能相关 在编写爬虫时,性能的消耗主要在IO请求中,当单进程单线程模式下请求URL时必然会引起等待,从而使得请求整体变慢. import requests def fetch_async(url): ...

  7. Cscope 安装和使用

    CScope 安装和使用 一.安装 1. 软件下载 https://sourceforge.net/projects/cscope/files/ 2. 解压 3. 安装 ./configure --p ...

  8. Javascript-- jQuery动画篇(2)

    动画效果 前面的 hide/show,slide in/out 其实也具有动画效果,本篇介绍使用 animate()实现自定义动画效果. 基本语法如下: $(selector).animate({pa ...

  9. U盘做了一个启动盘来安装Ubuntu,装好后,U盘不能进行格式化了,现在说一下网上找的方法

    参考网址:http://wenwen.sogou.com/z/q289778573.htm 说是这种情况需要对U盘进行低级格式化,具体方法如下: 你可以尝试使用diskpart命令 ① 以管理员身份运 ...

  10. python kd树 搜索 代码

    kd树就是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构,可以运用在k近邻法中,实现快速k近邻搜索.构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,依次选择坐标轴对空间 ...