bzoj4025
首先我们要知道,怎么去维护一个是否是二分图
二分图的充要条件:点数>=2且无奇环
重点就是不存在奇环,怎么做呢
考虑随便维护一个图的生成树,不难发现,如果一条边加入后,形成奇环的话就不是二分图
否则的话,我们可以无视这条边,因为如果之后再新加入一条边和这条边形成了一个奇环
那么新加入的边一定和原来生成树上的边也能形成奇环
所以我们直接维护一棵生成树即可
然后裸的想法就来了:上lct,维护以离开时间为边权的最大生成树,每次加边弹出环上最早离开的边
然后还是那句话:cdq大法好
我们可以对时间线分治,考虑每条边对应时间段的影响
这样就只有加边而不用删边了,我们可以用并查集维护
然而应该怎么用并查集维护路径的奇偶性呢?方法是膜拜popoqqq的程序的,我简单说明一下
我们给每个点一个权值c,我们定义一个点i到并查集根的权值c的xor和(不包括根)为d[i]
定义两点间路径奇偶性为dis(x,y)=d[x] xor d[y]
当加入一条边x-y且x、y不连通时,假设p[x]是x所在并查集的根,并且我们现在把x所在集合并到y所在集合下
我们就令c[p[x]]=d[x] xor d[y] xor 1(d[]为加入这条边之前的值)
这个操作的保证了每个点权值最多被赋值一次
上述做法为什么能求出两点间路径长的奇偶性呢?我们来证明一下
首先是有边直接相连的两个点x,y,根据A xor B xor B=1的性质
可得dis(x,y)=d[x](加入边之前的) xor d[y] xor c[p[x]](加入边之前的)=d[x] xor d[x] xor d[y] xor d[y] xor 1=1
并且以后再加入别的边改变并查集后,dis(x,y)仍然为1(还是可以通过xor性质得知)
对于没有边直接连的两点x,y,我们只要证明dis(x,y)=dis(po[x],y) xor 1 即可(po[x]为x的一个邻居)
根据定义可得dis(x,y)=d[x] xor d[y] xor d[po[x]] xor d[po[x]]=dis(x,po[x]) xor dis(po[x],y)=1 xor dis(po[x],y)
所以通过上述方法,我们可以用并查集维护路径长的奇偶性
其他与bzoj3237的处理方法有些类似,并不需要可持久化,只需要栈来恢复即可
type node=record
x,y,s,t:longint;
end; var c,d,fa:array[..] of longint;
e:array[..] of node;
te:array[..*] of node;
st:array[..*] of longint;
ans:array[..] of boolean;
en,top,t,n,m,len,i,x,y,a,b:longint; procedure swap(var a,b:longint);
var c:longint;
begin
c:=a;
a:=b;
b:=c;
end; function getf(x:longint):longint;
begin
while fa[x]<>x do x:=fa[x]; //路径压缩是均摊,所里这里不需要
exit(fa[x]);
end; function dis(x:longint):longint;
begin
dis:=;
while fa[x]<>x do
begin
dis:=dis xor c[x];
x:=fa[x];
end;
end; procedure union(x,y,w:longint);
begin
if d[x]>d[y] then swap(x,y); //按深度合并
fa[x]:=y;
inc(en);
st[en]:=x;
c[x]:=w;
if d[x]=d[y] then
begin
inc(en);
st[en]:=-y;
inc(d[y]);
end;
end; procedure rebuild(be:longint);
var x:longint;
begin
while be<>en do //两种情况的恢复
begin
x:=st[en];
if x< then
dec(d[-x])
else begin
fa[x]:=x;
c[x]:=;
end;
dec(en);
end;
end; procedure add(x,y,a,b:longint);
begin
inc(len);
e[len].x:=x;
e[len].y:=y;
e[len].s:=a;
e[len].t:=b;
end; procedure cdq(m,l,r:longint);
var mid,x,y,w,be,j,dow:longint;
begin
be:=en;
mid:=(l+r) shr ;
for i:= to m do
if (e[i].s=l) and (e[i].t=r) then
begin
x:=getf(e[i].x);
y:=getf(e[i].y);
w:=dis(e[i].x) xor dis(e[i].y) xor ;
if x<>y then union(x,y,w)
else if w= then
begin
for j:=l to r do
ans[j]:=false;
rebuild(be);
exit;
end;
end;
if l=r then ans[l]:=true
else begin
len:=;
dow:=top;
for i:= to m do //划分边集
begin
if (e[i].s=l) and (e[i].t=r) then continue;
inc(top);
te[top]:=e[i];
if e[i].t<=mid then
begin
inc(len);
e[len]:=e[i];
end
else if e[i].s<=mid then
add(e[i].x,e[i].y,e[i].s,mid);
end;
cdq(len,l,mid);
len:=;
for i:=top downto dow+ do
if te[i].s>mid then
begin
inc(len);
e[len]:=te[i];
end
else if te[i].t>mid then
add(te[i].x,te[i].y,mid+,te[i].t);
top:=dow;
cdq(len,mid+,r);
end;
rebuild(be);
end; begin
readln(n,m,t);
for i:= to m do
begin
readln(x,y,a,b);
inc(a);
if a>b then continue;
add(x,y,a,b);
end;
for i:= to n do
begin
fa[i]:=i;
d[i]:=;
end;
cdq(m,,t);
for i:= to t do
if ans[i] then writeln('Yes') else writeln('No');
end.
bzoj4025的更多相关文章
- BZOJ4025 二分图 分治 并查集 二分图 带权并查集按秩合并
原文链接http://www.cnblogs.com/zhouzhendong/p/8683831.html 题目传送门 - BZOJ4025 题意 有$n$个点,有$m$条边.有$T$个时间段.其中 ...
- BZOJ4025 二分图(线段树分治+并查集)
之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...
- 【BZOJ4025】二分图(线段树分治,并查集)
[BZOJ4025]二分图(线段树分治,并查集) 题面 BZOJ 题解 是一个二分图,等价于不存在奇环. 那么直接线段树分治,用并查集维护到达根节点的距离,只计算就好了. #include<io ...
- 【BZOJ4025】二分图 LCT
[BZOJ4025]二分图 Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于 ...
- [BZOJ4025]二分图(线段树分治,并查集)
4025: 二分图 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 2191 Solved: 800[Submit][Status][Discuss] ...
- 【BZOJ4025】二分图(可撤销并查集+线段树分治)
题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...
- [bzoj4025]二分图_LCT
二分图 bzoj-4025 题目大意:给定一个n个节点的图,m条边,每条边有一个产生时间和一个删除时间,询问所有时间点是否是连通图. 注释:$1\le n\le 10^5$,$1\le m\le 2\ ...
- bzoj4025 二分图
支持加边和删边的二分图判定,分治并查集水之(表示我的LCT还很不熟--仅仅停留在极其简单的模板水平). 由于是带权并查集,并且不能路径压缩,所以对权值(到父亲距离的奇偶性)的维护要注意一下. 有一个小 ...
- BZOJ4025 二分图 线段树分治、带权并查集
传送门 如果边不会消失,那么显然可以带权并查集做(然后发现自己不会写带权并查集) 但是每条边有消失时间.这样每一条边产生贡献的时间对应一段区间,故对时间轴建立线段树,将每一条边扔到线段树对应的点上. ...
随机推荐
- iOS - 指定视图的圆角个数-b
平常设置视图的圆角最普遍的就是设置四个角的,方法也就是一句代码解决: view.layer.cornerRadius = 10; 四个圆角 但有时需求会是指定某个,或者特定哪几个角设置圆角,所以我们需 ...
- SharePoint 优化显示WebParts
在开发sharepoint中,经常遇到需要自定义显示列表中的一部分作为导航的内容, 如公告栏,新闻链接,最新动态等.... 我们通常需要显示一个列表的标题,并且限制字符长度, 外加一些条件,如按创建的 ...
- javascript基础之客户端事件驱动
我们知道,面向对象发展起来后,“一夜之间”,几乎所有的语言都能基于对象了,JavaScript也是基于对象的语言.用户在浏览器上的行为称作“事件”,之后引发的一系列动作,比如弹窗啦,改变浏览器大小啦, ...
- Codeforces Round #303 (Div. 2) E. Paths and Trees 最短路+贪心
题目链接: 题目 E. Paths and Trees time limit per test 3 seconds memory limit per test 256 megabytes inputs ...
- 【BZOJ】【2729】【HNOI2012】排队
排列组合+高精度 Orz PoPoQQQ 引用题解: 嗯……学习了一下python= =懒的写高精了 /************************************************ ...
- 20160728noip模拟赛zld
前言:单独对题面描述的评分-> [题解]把相邻长度为2的子串两两连边,跑欧拉路 /*明天再写,先贴一份方老师代码压压惊*/ #include<map> #include<sta ...
- 20160727noip模拟赛zld
首先最优策略肯定是这样的:我们取出这个序列中的最大值,然后将整个序列分为左右两部分, 那么我们一定先把左右两部分合起来然后再与这个值合并 那么我们可以得出一个基于最值查询(rmq)的的算法,但是zld ...
- lucas求组合数C(n,k)%p
Saving Beans http://acm.hdu.edu.cn/showproblem.php?pid=3037 #include<cstdio> typedef __int64 L ...
- centos6.5\win7双系统安装配置
一.安装所需软件 1.分区助手专业版PACNPro.exe(必需):用来对硬盘分区,将磁盘的一部分格式化成Linux可以识别的ext3格式 2.Ext2Fsd(硬盘安装必需,光盘安装不用):因为Win ...
- soap消息机制 讲解
SOAP(Simple Object Access Protocol,简单对象访问协议)作为一种信息交互协议在分布式应用中非常广泛,如WebService.在使用.Net开发WebService时候, ...