C131【模板】线段树分治+并查集 P5787 线段树分治
视频链接:C131【模板】线段树分治+并查集 P5787 线段树分治_哔哩哔哩_bilibili
D24 二分图判定 染色法 - 董晓 - 博客园 (cnblogs.com)
C124 扩展域并查集 P2024 [NOI2001] 食物链 - 董晓 - 博客园 (cnblogs.com)
P5787 二分图 /【模板】线段树分治 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
// 线段树分治 O(mlognlogk) #include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define pii pair<int,int> #define ls (u<<1) #define rs (u<<1|1) #define mid ((l+r)>>1) const int N=400005; int n,m,k,p[N],high[N],top; struct node{ int x,y,hy; }st[N]; //栈 vector<pii> tr[N]; //节点 bool ans[N]; int find(int x){ //查找根 while(x!=p[x]) x=p[x]; return p[x]; } void merge(int x,int y){ //合并集合 x=find(x),y=find(y); if(high[x]>high[y]) swap(x,y); st[++top]={x,y,high[y]}; p[x]=y; high[y]+=(high[x]==high[y]); //相等则高度+1 } void insert(int u,int l,int r,int L,int R,pii e){ if(L>r||R<l) return; if(L<=l&&r<=R) return tr[u].push_back(e); insert(ls,l,mid,L,R,e); insert(rs,mid+1,r,L,R,e); } void solve(int u,int l,int r){ int flag=0; //0没有奇环 int now=top; for(auto e:tr[u]){ merge(e.first, e.second+n); merge(e.second, e.first+n); if(find(e.first)==find(e.second)){ flag=1; break; //有奇环则中断 } } if(!flag){ if(l==r) ans[l]=1; //是二分图 else solve(ls,l,mid),solve(rs,mid+1,r); } while(top>now){ //撤销合并 node t=st[top--]; p[t.x]=t.x; high[t.y]=t.hy; } } int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=2*n;i++) p[i]=i; for(int i=1,x,y,l,r;i<=m;i++){ scanf("%d%d%d%d",&x,&y,&l,&r); insert(1,1,k,l+1,r,{x,y}); //插入时间线 } solve(1,1,k); for(int i=1;i<=k;i++)puts(ans[i]?"Yes":"No"); }
雷同题:
CF19E Fairy - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
// 线段树分治 O(nlognlogn) #include <iostream> #include <cstring> #include <algorithm> #include <vector> using namespace std; #define ls (u<<1) #define rs (u<<1|1) #define mid ((l+r)>>1) #define pii pair<int,int> const int N=10005; int n,m,top; int p[N<<1],siz[N<<1]; //并查集 struct node{ int x,y; }st[N<<1]; //栈 int find(int x){ //查找根 return p[x]==x?x:find(p[x]); } void merge(int x,int y){ //合并集合 x=find(x),y=find(y); if(x==y) return; if(siz[x]>siz[y])swap(x,y); st[++top]={x,y}; p[x]=y; siz[y]+=siz[x]; } vector<pii> tr[N<<2]; //节点 vector<int> ans; void insert(int u,int l,int r,int L,int R,pii e){ if(L>r||R<l) return; if(L<=l&&r<=R)return tr[u].push_back(e); insert(ls,l,mid,L,R,e); insert(rs,mid+1,r,L,R,e); } void solve(int u,int l,int r){ int flag=0; //0没有奇环 int now=top; for(auto e:tr[u]){ merge(e.first, e.second+n); merge(e.second, e.first+n); if(find(e.first)==find(e.second)){ flag=1; break; //有奇环则中断 } } if(!flag){ if(l==r) ans.push_back(l); //是二分图 else solve(ls,l,mid),solve(rs,mid+1,r); } while(top>now){ //撤销合并 node t=st[top--]; p[t.x]=t.x; siz[t.y]-=siz[t.x]; } } int main(){ scanf("%d%d",&n,&m); if(m==0){puts("0");exit(0);} for(int i=1;i<=n<<1;i++) p[i]=i,siz[i]=1; for(int i=1,x,y;i<=m;i++){ scanf("%d%d",&x,&y); if(i>1) insert(1,1,m,1,i-1,{x,y}); if(i<m) insert(1,1,m,i+1,m,{x,y}); } solve(1,1,m); printf("%d\n",ans.size()); for(int i=0;i<ans.size();i++)printf("%d ",ans[i]); }
分类:
C 数据结构
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!