显然一个图是二分图当且仅当图中不存在一个奇环。那么我们用lct维护一个树形结构,如果不存在一条非树边,它连接的两个点在树上的距离为偶数,那么就是一个二分图。那么我们按时间离线之后维护一个树形结构和一个边的集合,集合中的边连接的两点在树上的距离为偶数。那么这个集合为空集则为二分图。
那么如果出现奇环,留下拿一条边在树上就成了问题。显然消失时间晚的可以存在的更久,因此维护一个消失时间的最大生成树(森林)即可。
AC代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100005
#define M 300005
using namespace std;
int n,m,cnt,pt,b[M],c[M][2],val[M],sz[M],fa[M],q[M];
bool bo[N<<1],flag[N<<1],rev[M];
struct graph{
int fst[N],nxt[N<<1];
void add(int x,int y){
nxt[y]=fst[x]; fst[x]=y;
}
}g1,g2;
struct node{ int x,y; }a[N<<1];
int read(){
int x=0; char ch=getchar();
while (ch<'0' || ch>'9') ch=getchar();
while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
return x;
}
bool isrt(int x){
return c[fa[x]][0]!=x && c[fa[x]][1]!=x;
}
void maintain(int x){
val[x]=x; sz[x]=(x>n)?1:0;
if (c[x][0]){
sz[x]+=sz[c[x][0]];
if (b[val[c[x][0]]]<b[val[x]]) val[x]=val[c[x][0]];
}
if (c[x][1]){
sz[x]+=sz[c[x][1]];
if (b[val[c[x][1]]]<b[val[x]]) val[x]=val[c[x][1]];
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l=(c[y][0]==x)?0:1,r=l^1;
if (!isrt(y))
if (c[z][0]==y) c[z][0]=x; else c[z][1]=x;
fa[x]=z; fa[y]=x; fa[c[x][r]]=y;
c[y][l]=c[x][r]; c[x][r]=y;
maintain(y); maintain(x);
}
void pushdown(int x){
if (rev[x]){
swap(c[x][0],c[x][1]);
rev[c[x][0]]^=1; rev[c[x][1]]^=1; rev[x]=0;
}
}
void splay(int x){
int y,z,i,tp=1; q[1]=x;
for (i=x; !isrt(i); i=fa[i]) q[++tp]=fa[i];
for (i=tp; i; i--) pushdown(q[i]);
for (; !isrt(x); rotate(x)){
y=fa[x]; z=fa[y];
if (!isrt(y))
if ((c[y][0]==x)^(c[z][0]==y)) rotate(x); else rotate(y);
}
}
void acss(int x){
int y=0;
for (; x; y=x,x=fa[x]){
splay(x); c[x][1]=y; maintain(x);
}
}
void makert(int x){
acss(x); splay(x); rev[x]^=1;
}
void link(int x,int y){
makert(x); fa[x]=y;
}
void cut(int x,int y){
makert(x); acss(y); splay(y); fa[x]=c[y][0]=0; maintain(y);
}
int findrt(int x){
acss(x); splay(x);
while (c[x][0]) x=c[x][0]; return x;
}
void ins(int x,int y,int z){
int u=findrt(x),v=findrt(y);
if (x==y){ pt++; flag[z]=1; return; }
if (u!=v){
bo[z]=1; link(x,z+n); link(y,z+n);
} else{
makert(x); acss(y); splay(y);
u=val[y]-n;
if (b[u+n]<b[z+n]){
if (!(sz[y]&1)){ pt++; flag[u]=1; }
cut(a[u].x,u+n); cut(a[u].y,u+n);
link(x,z+n); link(y,z+n);
bo[u]=0; bo[z]=1;
} else if (!(sz[y]&1)){ pt++; flag[z]=1; }
}
}
int main(){
n=read(); m=read(); cnt=read(); int i,j;
for (i=1; i<=n; i++){ val[i]=1; b[i]=1000000000; }
for (i=1; i<=m; i++){
a[i].x=read(); a[i].y=read();
g1.add(read()+1,i); g2.add(b[i+n]=read()+1,i);
sz[i+n]=1; val[i+n]=i+n;
}
for (i=1; i<=cnt; i++){
for (j=g1.fst[i]; j; j=g1.nxt[j]) ins(a[j].x,a[j].y,j);
for (j=g2.fst[i]; j; j=g2.nxt[j])
if (bo[j]){ cut(a[j].x,j+n); cut(a[j].y,j+n); } else if (flag[j]) pt--;
puts(pt?"No":"Yes");
}
return 0;
}
by lych
2016.5.2