我们注意到如果出现奇环就爆炸,所以我们维护并查集即可,但是如果要连u,v我们考虑u、v到根的距离分别为x,y如果(x+y)%2==0那么根直接合并,但是如果是奇数那么久新建一个点变成x和y的父亲,注意用深度维护平衡。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define xx first
#define yy second
#define mp(a,b) make_pair(a,b)
using namespace std;
typedef long long LL;
typedef double db;
const int maxn=200005;
int ans[maxn];
struct pi{
int u,v;
int l,r;
}pp;
int fa[maxn];
int dep[maxn];
typedef pair<int ,int>p1;
int cnt;
void divide(int l,int r,vector<pi>g){
int p=g.size();
vector<p1>gg;
gg.clear();
int flag=0;
int pre=cnt;
for(int i=0;i<p;i++){
if(g[i].l<=l&&g[i].r>=r){
int x=g[i].u;
int x1=0;
int y=g[i].v;
int y1=0;
while(fa[x]!=x){
x=fa[x];
x1++;
}
while(fa[y]!=y){
y=fa[y];
y1++;
}
gg.push_back(mp(x,dep[x]));
gg.push_back(mp(y,dep[y]));
if(x==y){
if((x1+y1)%2==0)
flag=1;
}
else{
if((x1+y1)%2==0){
if(dep[x]<dep[y]){
swap(x,y);
}
fa[y]=x;
dep[x]=max(dep[x],dep[y]+1);
}
else{
++cnt;
fa[x]=cnt;
fa[y]=cnt;
fa[cnt]=cnt;
dep[cnt]=max(dep[x],dep[y]);
}
}
}
}
if(flag){
for(int i=l;i<=r;i++) ans[i]=1;
}
if(l==r){
p=gg.size();
for(int i=p-1;i>=0;i--){
fa[gg[i].xx]=gg[i].xx;
dep[gg[i].xx]=gg[i].yy;
}
gg.clear();
cnt=pre;
return ;
}
int mid=(l+r)/2;
vector<pi>g1,g2;
g1.clear();
g2.clear();
for(int i=0;i<p;i++){
if(g[i].l<=l&&g[i].r>=r) continue;
if(g[i].l<=mid) g1.push_back(g[i]);
if(g[i].r>mid) g2.push_back(g[i]);
}
divide(l,mid,g1);
divide(mid+1,r,g2);
p=gg.size();
for(int i=p-1;i>=0;i--){
fa[gg[i].xx]=gg[i].xx;
dep[gg[i].xx]=gg[i].yy;
}
gg.clear();
cnt=pre;
}
int main()
{
int n,m,t;
cin>>n>>m>>t;
for(int i=1;i<=2*n;i++){
fa[i]=i;
dep[i]=1;
}
vector<pi>g;
g.clear();
for(int i=0;i<m;i++){
scanf("%d%d%d%d",&pp.u,&pp.v,&pp.l,&pp.r);
if(pp.l==pp.r) continue;
pp.r--;
g.push_back(pp);
}
cnt=n;
divide(0,t-1,g);
for(int i=0;i<t;i++){
if(ans[i]) printf("No\n");
else printf("Yes\n");
}
return 0;
}