Я слышал, что хорошее название подается из Oier
Смысл проблем
м ребра п точек, общее время Т.
Хотя существует время каждый день. За каждый раз, когда я спросил, фигура, является ли двудольным графом.
Проблема решения идеи
Узнали теории графов, мы знаем, что граф является двудольным графом, если и только если он сделал странное кольцо.
Очевидно, что если две точки не являются ни, то можно подключить непосредственно к стороне, в которой, независимо от других условий. Таким образом, мы должны знать, непересекающиеся-набор.
Я начал видеть сторона исчезает, то аутист.
После dalao советов, найти вид под названием отзывной непересекающегося набором вещь.
Принимая во внимание текущее время каждая сторона, которая может быть выражена как журнал п узлов сегментов дерева.
снова обходе дерева линии, а затем добавили с текущим узлом. Рекурсивный о его сыне, а затем отмененной стороне.
Судья рассматривать насилие нечетного кольцо прыжка, будет висеть. Набор эвристического слияния.
Эвристическое слияние должно быть соединено между корнем и корневой частью, таким образом, мы будем иметь дело даже с небольшими краями, вес края изменяется, может быть подключен непосредственно эквивалент к краю.
код
#include<bits/stdc++.h>
#define lson o<<1,l,mid
#define rson o<<1|1,mid+1,r
using namespace std;
const int sz=2e5+527;
int n,m,T;
int dep[sz],f[sz],d[sz];
queue<int>q[sz<<1];
int getfa(int x) { return x==f[x]?x:getfa(f[x]); }
int getdis(int x) { return x==f[x]?0:d[x]^getdis(f[x]); }
struct Edge{
int u,v,w;
}e[sz];
void insert(int o,int l,int r,int x,int y,int num){
if(x<=l&&r<=y) return (void)(q[o].push(num));
int mid=(l+r)>>1;
if(x<=mid) insert(lson,x,y,num);
if(mid<y) insert(rson,x,y,num);
}
void resum(stack<Edge>S){
while(!S.empty()){
d[f[S.top().u]=S.top().u]=0;
dep[S.top().v]-=S.top().w;
S.pop();
}
}
void solve(int o,int l,int r){
stack<Edge>S;
while(!q[o].empty()){
int num=q[o].front();
q[o].pop();
int x=e[num].u,y=e[num].v;
int fx=getfa(x),fy=getfa(y);
int w=getdis(x)^getdis(y)^1;
if(fx==fy&&w){
for(int i=l;i<=r;i++) puts("No");
return (void)(resum(S));
}
if(fx!=fy){
if(dep[fx]>dep[fy]) swap(fx,fy),swap(x,y);
Edge cur=(Edge){fx,fy,0};
f[fx]=fy,d[fx]=w;
if(dep[fx]==dep[fy]) ++dep[fy],cur.w=1;
S.push(cur);
}
}
if(l==r){ resum(S);return (void)(puts("Yes")); }
int mid=(l+r)>>1;
solve(lson);
solve(rson);
resum(S);
}
int main(){
scanf("%d%d%d",&n,&m,&T);
int u,v,L,R;
for(int i=1;i<=n;i++) f[i]=i;
for(int i=1;i<=m;i++){
scanf("%d%d%d%d",&u,&v,&L,&R);
L++;
e[i]=(Edge){u,v,1};
insert(1,1,T,L,R,i);
}
solve(1,1,T);
}