支持加边和删边的二分图判定,分治并查集水之(表示我的LCT还很不熟……仅仅停留在极其简单的模板水平)。

由于是带权并查集,并且不能路径压缩,所以对权值(到父亲距离的奇偶性)的维护要注意一下。

有一个小优化:如果当前图已经不是二分图就不再继续dfs线段树,直接把区间内的每个答案设为No后回溯即可。

这次写了个按size合并,不过随机合并比按size合并还快一点是什么鬼……

按size合并的代码:

/**************************************************************
Problem: 4025
User: hzoier
Language: C++
Result: Accepted
Time:13616 ms
Memory:39288 kb
****************************************************************/ #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=;
void addedge(int,int,int);
void solve(int,int,int);
bool mergeset(int,int,vector<int>&);
void cut(int);
int prt[maxn],size[maxn];
bool d[maxn]={false};
int n,m,e,x,y,s,t;
vector<int>u[maxn<<],v[maxn<<];
int main(){
scanf("%d%d%d",&n,&e,&m);
for(int i=;i<=n;i++){
prt[i]=i;
size[i]=;
}
while(e--){
scanf("%d%d%d%d",&x,&y,&s,&t);
s++;
addedge(,m,);
}
solve(,m,);
return ;
}
void addedge(int l,int r,int rt){
if(s<=l&&t>=r){
u[rt].push_back(x);
v[rt].push_back(y);
return;
}
int mid=(l+r)>>;
if(s<=mid)addedge(l,mid,rt<<);
if(t>mid)addedge(mid+,r,rt<<|);
}
void solve(int l,int r,int rt){
vector<int>stk;
bool ok=true;
for(int i=;i<(int)u[rt].size();i++)if(mergeset(u[rt][i],v[rt][i],stk)){
for(int j=l;j<=r;j++)printf("No\n");
ok=false;
break;
}
if(ok){
if(l==r)printf("Yes\n");
else{
int mid=(l+r)>>;
solve(l,mid,rt<<);
solve(mid+,r,rt<<|);
}
}
if(!stk.empty())for(int i=(int)stk.size()-;i>=;i--)cut(stk[i]);
}
bool mergeset(int x,int y,vector<int>&a){
bool dx=false,dy=false;
int rx=x,ry=y;
while(prt[rx]!=rx){
dx^=d[rx];
rx=prt[rx];
}
while(prt[ry]!=ry){
dy^=d[ry];
ry=prt[ry];
}
if(rx==ry)return dx==dy;
if(size[rx]>size[ry])swap(rx,ry);
prt[rx]=ry;
size[ry]+=size[rx];
d[rx]=dx==dy;
a.push_back(rx);
return false;
}
void cut(int x){
int y=prt[x];
while(prt[y]!=y){
size[y]-=size[x];
y=prt[y];
}
size[y]-=size[x];
prt[x]=x;
d[x]=false;
}

随机合并的代码(其实两份代码差别并不大):

 /**************************************************************
Problem: 4025
User: hzoier
Language: C++
Result: Accepted
Time:13104 ms
Memory:38896 kb
****************************************************************/ #include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
inline int randint(){
static int a=,b=,c=,x=,p=;
x=a*x*x+b*x+c;x%=p;
return x<?(x=-x):x;
}
const int maxn=;
void addedge(int,int,int);
void solve(int,int,int);
bool mergeset(int,int,vector<int>&);
int prt[maxn];
bool d[maxn]={false};
int n,m,e,x,y,s,t;
vector<int>u[maxn<<],v[maxn<<];
int main(){
scanf("%d%d%d",&n,&e,&m);
for(int i=;i<=n;i++)prt[i]=i;
while(e--){
scanf("%d%d%d%d",&x,&y,&s,&t);
s++;
addedge(,m,);
}
solve(,m,);
return ;
}
void addedge(int l,int r,int rt){
if(s<=l&&t>=r){
u[rt].push_back(x);
v[rt].push_back(y);
return;
}
int mid=(l+r)>>;
if(s<=mid)addedge(l,mid,rt<<);
if(t>mid)addedge(mid+,r,rt<<|);
}
void solve(int l,int r,int rt){
vector<int>stk;
bool ok=true;
for(int i=;i<(int)u[rt].size();i++)if(mergeset(u[rt][i],v[rt][i],stk)){
for(int j=l;j<=r;j++)printf("No\n");
ok=false;
break;
}
if(ok){
if(l==r)printf("Yes\n");
else{
int mid=(l+r)>>;
solve(l,mid,rt<<);
solve(mid+,r,rt<<|);
}
}
if(!stk.empty())for(int i=(int)stk.size()-;i>=;i--){
prt[stk[i]]=stk[i];
d[i]=false;
}
}
bool mergeset(int x,int y,vector<int>&a){
bool dx=false,dy=false;
int rx=x,ry=y;
while(prt[rx]!=rx){
dx^=d[rx];
rx=prt[rx];
}
while(prt[ry]!=ry){
dy^=d[ry];
ry=prt[ry];
}
if(rx==ry)return dx==dy;
if(randint()&)swap(rx,ry);
prt[rx]=ry;
d[rx]=dx==dy;
a.push_back(rx);
return false;
}

感觉越来越忧伤,却没有办法排解,唉……

bzoj4025 二分图的更多相关文章

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

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

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

    之前学了一下线段树分治,这还是第一次写.思想其实挺好理解,即离线后把一个操作影响到的时间段拆成线段树上的区间,并标记永久化.之后一块处理,对于某个节点表示的时间段,影响到他的就是该节点一直到线段树根的 ...

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

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

  4. [bzoj4025]二分图_LCT

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

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

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

  6. bzoj4025 二分图 [分治,并查集]

    传送门 思路 是二分图的充要条件:图没有奇环. 考虑按时间分治,用可撤销并查集维护点到根的距离. 仍然可以用一个小trick把两点连边变成根连边,可以看这里. 每次连边时若不连通则连上,否则判一下有没 ...

  7. bzoj4025: 二分图 lct

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

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

    传送门 线段树分治好题. 这道题实际上有很多不同的做法: cdq分治. lct. - 而我学习了dzyo的线段树分治+并查集写法. 所谓线段树分治就是先把操作分成lognlognlogn个连续不相交的 ...

  9. BZOJ4025: 二分图【线段树分治】【带撤销的并查集】

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

随机推荐

  1. [LeetCode] Rising Temperature 上升温度

    Given a Weather table, write a SQL query to find all dates' Ids with higher temperature compared to ...

  2. 火狐下js的日期比较的方法

    function tab(date1,date2){ var oDate1 = new Date(date1); var oDate2 = new Date(date2); if(oDate1.get ...

  3. AngularJS Scope(作用域)

    1. AngularJS Scope(作用域) Scope(作用域) 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带. Scope 是一个对象,有可用的方法和属性. Sc ...

  4. [转]CSS如何设置html table表格边框样式

    原文地址:http://www.divcss5.com/wenji/w503.shtml 对table设置css样式边框,分为几种情况: 1.只对table设置边框 2.对td设置边框 3.对tabl ...

  5. WebStorm 2016.2.3的安装与汉化

    WebStorm是一款功能出色的JavaScript开发工具.号称是""Web前端开发神器"."最强大的HTML5编辑器"."最智能的Jav ...

  6. 由于服务器意外的断电,导致SQL SERVER服务器上数据库出现“置疑”而无法使用,

    来自百度 1.停止数据库服务器,将数据库MDF文件和LDF文件复制备份一份2.启动数据库服务器,删除置疑的数据库3.仅用备份的数据库MDF文件附加数据库,sp_attach_db或者sp_attach ...

  7. DSO之光度标定

    光度标定(Photometric Camera Calibration)是DSO(Direct Sparse Odometry)论文中比较特别的一部分.常规的vSLAM不太考虑光度标定的问题.比如基于 ...

  8. XCode8 App上传AppStore更新

    1.在这个网站中https://itunesconnect.apple.com 点击"我的APP" 选取需要更新的app 2.点击加号 版本或平台,填写对应的更新版本 3.配置Xc ...

  9. 解决UINavigationController在pushViewController时出现的"卡顿"问题

    进行开发中,遇到了个小问题: 在使用UINavigationController的-pushViewController:animated:执行入栈一个子控制器操作时(即最新栈顶子控制器),会出现推出 ...

  10. css-css权威指南学习笔记7

    第11章 表布局 1.border-spacing,单元格边框间距,可以有两个或一个值,两个值前者表示水平间距,后者垂直间距. 2.border-collapse值为collapse时不可设置padd ...