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。

Solution

首先看怎么静态判能不能二分,一条一条边加进去,如果这条边加上会变成一个环,并且这个环还是奇环,那就不能二分;反之,可以

然后看动态的,动态的麻烦就在删除,因为可能把一条树边删掉之后,会有一条非树边代替它变成一条树边,这个做不了;所以就弄一个LCT维护这个树,维护这个图以删除时间为关键字的最大生成树,这样就不会有上述情况发生了

然后按照套路,离线解决

(PS:从早上开始调,一直调到晚上,开始的时候造数据的程序还写错了,会使标程RE,然后有一次其实改对了,但因为数据造错,一直拍不上,结果就和gt拿了一个正确的程序调了半个小时)

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=100000+10,MAXM=200000+10,inf=0x3f3f3f3f;
int n,m,tT,V[MAXN+MAXM],sum,f[MAXN+MAXM];
struct edge{
int u,v;
};
edge side[MAXM];
struct data{
int opt,val,t,id;
inline bool operator < (const data &A) const {
return t<A.t||t==A.t&&opt>A.opt;
};
};
data p[MAXM<<1];
#define lc(x) ch[(x)][0]
#define rc(x) ch[(x)][1]
struct LCT{
int ch[MAXN+MAXM][2],fa[MAXN+MAXM],rev[MAXN+MAXM],Mn[MAXN+MAXM],id[MAXN+MAXM],stack[MAXN+MAXM],cnt,val[MAXN+MAXM],size[MAXN+MAXM];
inline void init()
{
memset(Mn,inf,sizeof(Mn));
memset(val,inf,sizeof(val));
}
inline bool nroot(int x)
{
return lc(fa[x])==x||rc(fa[x])==x;
}
inline void reverse(int x)
{
std::swap(lc(x),rc(x));
rev[x]^=1;
}
inline void pushup(int x)
{
size[x]=size[lc(x)]+size[rc(x)]+1;
Mn[x]=val[x],id[x]=x;
if(Mn[lc(x)]<Mn[x])Mn[x]=Mn[lc(x)],id[x]=id[lc(x)];
if(Mn[rc(x)]<Mn[x])Mn[x]=Mn[rc(x)],id[x]=id[rc(x)];
}
inline void pushdown(int x)
{
if(rev[x])
{
if(lc(x))reverse(lc(x));
if(rc(x))reverse(rc(x));
rev[x]=0;
}
}
inline void rotate(int x)
{
int f=fa[x],p=fa[f],c=(rc(f)==x);
if(nroot(f))ch[p][rc(p)==f]=x;
fa[ch[f][c]=ch[x][c^1]]=f;
fa[ch[x][c^1]=f]=x;
fa[x]=p;
pushup(f);
pushup(x);
}
inline void splay(int x)
{
cnt=0;
stack[++cnt]=x;
for(register int i=x;nroot(i);i=fa[i])stack[++cnt]=fa[i];
while(cnt)pushdown(stack[cnt--]);
for(register int y=fa[x];nroot(x);rotate(x),y=fa[x])
if(nroot(y))rotate((lc(y)==x)==(lc(fa[y])==y)?y:x);
pushup(x);
}
inline void access(int x)
{
for(register int y=0;x;x=fa[y=x])splay(x),rc(x)=y,pushup(x);
}
inline int findroot(int x)
{
access(x);splay(x);
while(lc(x))pushdown(x),x=lc(x);
splay(x);
return x;
}
inline void makeroot(int x)
{
access(x);splay(x);reverse(x);
}
inline void split(int x,int y)
{
makeroot(x);access(y);splay(y);
}
inline void link(int x,int y)
{
makeroot(x);fa[x]=y;
}
inline void cut(int x,int y)
{
split(x,y);fa[x]=lc(y)=0;pushup(y);
}
};
LCT T;
#undef lc
#undef rc
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char c='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(c!='\0')putchar(c);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void add(int now)
{
int u=side[p[now].id].u,v=side[p[now].id].v,sn=p[now].id+n;
if(u==v)
{
f[sn-n]=1;sum++;
return ;
}
if(T.findroot(u)!=T.findroot(v))T.val[sn]=p[now].val,T.link(sn,u),T.link(sn,v),V[sn-n]=1;
else
{
T.split(u,v);
int so=T.id[v],nt=T.size[v]>>1;
if(p[now].val>T.Mn[v])
{
if(!(nt&1))sum++,f[so-n]=1;
T.cut(so,side[so-n].u);
T.cut(so,side[so-n].v);
T.val[sn]=p[now].val;
T.link(sn,u);
T.link(sn,v);
V[so-n]=0;V[sn-n]=1;
}
else if(!(nt&1))sum++,f[sn-n]=1;
}
}
inline void del(int now)
{
int sn=p[now].id+n;
sum-=f[sn-n];
if(V[sn-n])
{
V[sn-n]=f[sn-n]=0;
T.cut(sn,side[sn-n].u);T.cut(sn,side[sn-n].v);
}
else f[sn-n]=0;
}
int main()
{
read(n);read(m);read(tT);
for(register int i=1;i<=m;++i)
{
int u,v,st,ed;
read(u);read(v);read(st);read(ed);
side[i].u=u;side[i].v=v;
p[i].t=st;p[i].val=ed;p[i].id=i;p[i].opt=1;
p[i+m].t=ed;p[i+m].id=i;p[i+m].opt=0;
}
std::sort(p+1,p+m*2+1);
T.init();
for(register int i=1,j=1;i<=tT;++i)
{
for(;p[j].t<i&&j<=m*2;++j)
if(p[j].opt)add(j);
else del(j);
if(sum)puts("No");
else puts("Yes");
}
return 0;
}

【刷题】BZOJ 4025 二分图的更多相关文章

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

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

  2. bzoj 4025 二分图 分治+并查集/LCT

    bzoj 4025 二分图 [题目大意] 有n个点m条边,边会在start时刻出现在end时刻消失,求对于每一段时间,该图是不是一个二分图. 判断二分图的一个简单的方法:是否存在奇环 若存在奇环,就不 ...

  3. BZOJ 4025: 二分图 [线段树CDQ分治 并查集]

    4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...

  4. bzoj 4025: 二分图

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

  5. BZOJ 4025 二分图(时间树+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4025 [题目大意] 给出一张图,有些边只存在一段时间,问在一个每个时间段, 这张图是否 ...

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

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

  7. 「bzoj 4025: 二分图」

    题目 显然二分图没有奇环 于是考虑使用并查集维护一下看看是否存在奇环 我们可以考虑加权并查集,维护出\(x\)到\(fa_x\)的实际距离 由于我们只需要考虑奇偶性,于是我们处理出到根的路径异或一下就 ...

  8. bzoj 4025 二分图 lct

    题目传送门 题解: 首先关于二分图的性质, 就是没有奇环边. 题目其实就是让你判断每个时段之内有没有奇环. 其次 lct 只能维护树,(反正对于我这种菜鸟选手只会维护树), 那么对于一棵树来说, 填上 ...

  9. BZOJ 4025 二分图 LCT维护最大生成树

    怎么说呢,我也不知道该咋讲,你就手画一下然后 yy 一下就发现这么做是对的. 为什么我明明都想出来了,却还是讲不出来啊~ #include <cstdio> #include <ve ...

随机推荐

  1. 初始CSS模板

    /*开始 初始CSS模板 开始*/ body, div, address, blockquote, iframe, ul, ol, dl, dt, dd, li, dl, h1, h2, h3, h4 ...

  2. 一个web应用的诞生(2)--使用模板

    经过了第一章的内容,已经可以做出一些简单的页面,首先用这种方式做一个登录页面,首先要创建一个login的路由方法: @app.route("/login",methods=[&qu ...

  3. Wince 中访问WCF服务

    由于本文并非WinCE开发普及篇,所以一些WinCE开发和WCF开发的基础还请移步百度和谷歌寻找答案,然后结合本文开发出WinCE中如何访问WCF,谢谢. 开发环境 IDE:Visual Studio ...

  4. 03-运行第一个docker容器

    环境选择 容器需要管理工具.runtime 和操作系统,我们的选择如下: 1.管理工具 - Docker Engine因为 Docker 最流行使用最广泛. 2.runtime - runc Dock ...

  5. idea下增加scala

    1 idea工具下,下载scala插件 2 idea下新建scala工程 File——New——module 如果按照上图,设置后点击下载,出现下图下载过慢情况下, 这里我选择了等待,大概等了半小时才 ...

  6. linux下各文件夹的结构说明及用途介绍(转载)

    详细介绍文档 转载文章路径 /bin:二进制可执行命令. /dev:设备特殊文件. /etc:系统管理和配置文件. /etc/rc.d:启动的配 置文件和脚本. /home:用户主目录的基点,比如用户 ...

  7. 关于0x80000000为什么等于-2147483648和负数在内存上储存的问题

    转载自大佬的博客https://blog.csdn.net/youyou362/article/details/72667951/ 1·先说明负数怎么储存 (1)十进制负数是以其补码储存在内存上. 验 ...

  8. 【Alpha】阶段第二次Scrum Meeting

    [Alpha]阶段第二次Scrum Meeting 工作情况 团队成员 今日已完成任务 明日待完成任务 刘峻辰 发表评论接口 更新评论接口 赵智源 部署实际项目 编写脚本实现持续集成 肖萌威 编写注册 ...

  9. Beta阶段第一次网络会议

    Beta阶段第一次网络会议 游戏问题 游戏细节特征不够明显,大小虽然随着电脑分辨率的不同变化着,但是存在清楚的问题 游戏中的提示信息不够,玩家无法快速了解游戏 游戏中背景声音过于单一 游戏AI太简单 ...

  10. Java Web文件上传原理分析(不借助开源fileupload上传jar包)

    Java Web文件上传原理分析(不借助开源fileupload上传jar包) 博客分类: Java Web   最近在面试IBM时,面试官突然问到:如果让你自己实现一个文件上传,你的代码要如何写,不 ...