并查集爆零

P5787 二分图 /【模板】线段树分治

@[Sktn0089](/user/375953) 调好了 ```cpp #include<bits/stdc++.h> #define ll long long using namespace std; const int maxn=1e6+10; ll n,m,k,x,y,l,r,d[maxn],siz[maxn],top,ans[maxn]; vector<pair<ll,ll> >edge[maxn]; pair<ll,ll> stk[maxn]; void modify(ll p,ll l,ll r,ll ql,ll qr,pair<ll,ll>pa) { if(ql<=l&&r<=qr) { edge[p].push_back(pa); return; } ll mid=l+r>>1; if(ql<=mid) modify(p<<1,l,mid,ql,qr,pa); if(mid<qr) modify(p<<1|1,mid+1,r,ql,qr,pa); } ll find(ll x) { if(d[x]==x) return x; return find(d[x]); } bool merge(pair<ll,ll>pa) { ll x=pa.first,y=pa.second; if(find(x)==find(y)) return false; int x1=find(x+n),y1=find(y); stk[++top]=make_pair(x1,y1); if(siz[x1]>siz[y1]) { d[y1]=x1; siz[x1]+=siz[y1]; } else { d[x1]=y1; siz[y1]+=siz[x1]; } x1=find(x),y1=find(y+n); stk[++top]=make_pair(x1,y1); if(siz[x1]>siz[y1]) { d[y1]=x1; siz[x1]+=siz[y1]; } else { d[x1]=y1; siz[y1]+=siz[x1]; } return true; } void split() { ll x=stk[top].first,y=stk[top].second; --top; if(d[x]==y) { siz[y]-=siz[x]; d[x]=x; } else { siz[x]-=siz[y]; d[y]=y; } } void dfs(ll p,ll l,ll r) { for(ll i=0;i<edge[p].size();i++) { if(!merge(edge[p][i])) { while(i--) { split(),split(); } return; } } if(l==r) { ans[l]=1; } else { ll mid=l+r>>1; dfs(p<<1,l,mid); dfs(p<<1|1,mid+1,r); } for(ll i=0;i<edge[p].size();i++) split(),split(); } int main() { scanf("%lld%lld%lld",&n,&m,&k); for(ll i=1;i<=n*2;i++) d[i]=i,siz[i]=1; for(ll i=1;i<=m;i++) { ll x,y,l,r; scanf("%lld%lld%lld%lld",&x,&y,&l,&r); if(++l>r) continue; modify(1,1,k,l,r,make_pair(x,y)); } dfs(1,1,k); for(ll i=1;i<=k;i++) if(ans[i]) printf("Yes\n"); else printf("No\n"); return 0; } ````
by Nityacke @ 2023-01-26 20:58:34


拓展域不是这么用的,要将能在一起的连在一起,一旦不能在一起的开始合并则说明有误
by Nityacke @ 2023-01-26 20:59:40


@[Ethereal_shadow](/user/568716) 感谢,是我一时脑抽
by Lgx_Q @ 2023-01-27 07:56:54


|