卡不掉自己怎么办(0分)
查看原帖
卡不掉自己怎么办(0分)
1109464
WTimeLlimit楼主2024/1/20 12:21
#include<bits/stdc++.h>
#define mid ((l+r)>>1)
#define ls (2*rt)
#define rs (2*rt+1)
#define up(i,a,b) for(auto i=a;i<=b;++i)
const int N=2e5+5;
using namespace std;
struct var { int x,y; } edge[2*N],sta[20*N];
vector<int> lis[4*N];
int n,m,t,psta,f[N],siz[N],len[N],ans[N];
var find(int x){
    if(f[x]==x) return {x,0};
    var ret=find(f[x]);
    return {ret.x,(ret.y+len[x])%2};
}
int merge(int x,int y){
    var xx=find(x),yy=find(y);
    int gx=xx.x,gy=yy.x;
    if(gx==gy){
        if(x!=y&&(xx.y+yy.y)%2==0) return 1;
        sta[++psta]={-1,-1};
        return 0;
    }
    if(siz[gx]>siz[gy]) swap(x,y),swap(xx,yy);
    f[gx]=gy,siz[gy]+=siz[gx],sta[++psta]={gx,gy},len[gx]=((yy.y+1-xx.y)%2+2)%2;
    return 0;
}
void undo(){
    var q=sta[psta--];
    if(q.x==-1) return;
    siz[q.y]-=siz[q.x],f[q.x]=q.x,len[q.x]=0;
}
void upd(int rt,int l,int r,int x,int y,int k){
    if(l>r||x>y) return;
    if(x<=l&&r<=y) return (void)lis[rt].push_back(k);
    if(x<=mid) upd(ls,l,mid,x,y,k);
    if(y>mid) upd(rs,mid+1,r,x,y,k);
}
void inq(int rt,int l,int r){
    for(int i=0;i<lis[rt].size();++i)
        if(merge(edge[lis[rt][i]].x,edge[lis[rt][i]].y)){
            for(int j=0;j<i;++j) undo();
            return;
        }
    if(r>l) inq(ls,l,mid),inq(rs,mid+1,r);
    if(l==r) ans[l]=1;
    int t=lis[rt].size();
    while(t--) undo();
}
signed main(){
    scanf("%d%d%d",&n,&m,&t); ++t;
    up(i,1,m){
        int u,v,sa,ta; 
        scanf("%d%d%d%d",&u,&v,&sa,&ta);
        edge[i]={u,v};
        upd(1,1,t,sa+1,ta,i);
    }
    up(i,1,n) f[i]=i,siz[i]=1;
    inq(1,1,t);
    up(i,1,t-1) 
        if(ans[i]) puts("Yes");
        else puts("No");
    return 0;
}
2024/1/20 12:21
加载中...