支持加边和删边的二分图判定,分治并查集水之(表示我的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. 百度地图demo

    以下代码拷贝成html,直接运行即能看到百度地图 <!DOCTYPE html><html> <head> <meta http-equiv="Co ...

  2. 如何解决ajax重复提交的问题

    如下一段代码: 先忽略我没引jquery.js的问题,这是一个案例. 当我们点击提交时,控制台输出两次e,在network里查看,可以看到我们的ajax传输了两次,造成了数据重复提交. 一种解释为bu ...

  3. Redis设计与实现读书笔记(一) SDS

    作为redis最基础的底层数据结构之一,SDS提供了许多C风格字符串所不具备的功能,为之后redis内存管理提供了许多方便.它们分别是: 二进制安全 减少字符串长度获取时间复杂度 杜绝字符串溢出 减少 ...

  4. phylogeny analysis

    Multiple Alignment: MUSCLE ProbCons T-Coffee ClustalW Alignment curation: Gblocks Remove positions w ...

  5. java学习笔记之IO一()

    1.缓冲输入文件 2.从内存输入 3.格式化的内存输入 4.基本的文本输出 示例: public class BrAndBwOrPwDemo { public static void main(Str ...

  6. 很不错的Intent用法 适用于正在开发的伙伴。自己看到了,也分享给大家吧。

    本文介绍Android中Intent的各种常见作用. 1 Intent.ACTION_MAIN String: android.intent.action.MAIN 标识Activity为一个程序的开 ...

  7. Android_server提示端口被占用

    root@android:/data/local/tmp # ./android_server IDA Android 32-bit remote debug server(ST) v1.19. He ...

  8. strchr()函数 和 strrchr() 函数

    strchr 定义于头文件 <string.h>char *strchr( const char *str, int ch );寻找ch(按照如同(char)ch的方式转换成char后)在 ...

  9. Neural Network Toolbox使用笔记1:数据拟合

    http://blog.csdn.net/ljp1919/article/details/42556261 Neural Network Toolbox为各种复杂的非线性系统的建模提供多种函数和应用程 ...

  10. web前端基础知识-(五)jQuery

    通过之前的学习我们已经了解了html.css.javascript的相关知识:本次我们就共同学习进阶知识:jQuery~ 一.什么是jQuery? jQuery其实就是一个轻量级的javascript ...