【题解】P5787 二分图 /【模板】线段树分治
二分图最简单的方法是染色法实现,但是扩展域并查集也可以实现,有两个集合 \(S,T\),具体的是相连边的两个点 \(x,y\) 总是在不同的两个集合中,若出现在同一集合中即不是一个二分图。
对于时间段建边考虑用线段树储存,线段树按照时间轴划分,将将对应时间区间的节点储存上当前连边操作,小时间区间总是被大时间区间包含。
可以看到 \(e_2\) 这个操作在互不相交的对应时间区间上都储存了,我们如何查询呢,我们从大区间依次加边,同时判断合法,如果[l,r]这个区间出现不合法的情况,我们输出 \(r-l+1\) 次 NO
并且他之后的小区间也不用遍历加边了,直接返回,否则直到叶子节点时输出 YES
。
当然返回要撤销对应的加边操作,我们用可撤销并查集,用栈储存当时的状态,不断回溯。
#include <bits/stdc++.h> #define ll long long #define int ll #define ls p<<1 #define rs p<<1|1 #define re register #define pb push_back #define pir pair<int,int> #define f(a,x,i) for(int i=a;i<=x;i++) #define fr(a,x,i) for(int i=a;i>=x;i--) #define lb(x) x&(-x); const int N=6e5+10; const int mod=1e9+7; using namespace std; int n,m,k; int u[N],v[N]; vector<int> t[N]; int fa[N],siz[N]; stack<pir> s; int find(int x){ while(x^fa[x]){ x=fa[x]; } return x; } void change(int p,int pl,int pr,int id,int l,int r){ if(pl>=l&&pr<=r){ t[p].push_back(id); return; } int mid=(pl+pr)>>1; if(l<=mid){ change(ls,pl,mid,id,l,r); } if(r>mid){ change(rs,mid+1,pr,id,l,r); } } void merge(int x,int y){ if(x==y){ return; } if(siz[x]>siz[y]){ swap(x,y); } s.push({x,siz[x]==siz[y]}); fa[x]=y; siz[y]+=(siz[x]==siz[y]); } void solve(int p,int l,int r){ int ok=1; int si=s.size(); for(int i=0;i<t[p].size();i++){ int id=t[p][i]; int x=find(u[id]),y=find(v[id]); if(x==y){ for(int j=l;j<=r;j++){ cout<<"No\n"; } ok=0; break; } merge(find(u[id]+n),y); merge(find(v[id]+n),x); } if(ok){ if(l==r){ cout<<"Yes\n"; } else{ int mid=(l+r)>>1; solve(ls,l,mid); solve(rs,mid+1,r); } } while(s.size()>si){ int x=s.top().first; siz[fa[x]]-=s.top().second; fa[x]=x; s.pop(); } } signed main(){ // freopen("xp1.in","r",stdin); ios::sync_with_stdio(0); cin.tie(nullptr); cin>>n>>m>>k; for(int i=1;i<=m;i++){ int l,r; cin>>u[i]>>v[i]>>l>>r; if(l^r){ change(1,1,k,i,l+1,r); } } for(int i=1;i<=n;i++){ fa[i]=i,siz[i]=1,fa[i+n]=i+n; } solve(1,1,k); return 0; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具