题解:
线段树分治裸题
apio t1是这个所以就学习了一下
#include <bits/stdc++.h> using namespace std; const int N=2e5+10; struct re{ int x,y; }a[N*2]; int b[N+20][5],cnt,now,n,m,k; int ls[N*15],rs[N*15],data[N*15],last[N+20]; int ph[N*4],pt[N*4],count2[N+20],f[N]; bool ft[N+20]; vector<int> ve[N]; #define mid (ph[x]+pt[x])/2 void change(int last,int &now,int h,int t,int goal,int goal2) { now=++cnt; if (h==t) { data[now]=goal2; return; } ls[now]=ls[last]; rs[now]=rs[last]; int mid2=(h+t)/2; if (goal<=mid2) change(ls[last],ls[now],h,mid2,goal,goal2); else change(rs[last],rs[now],mid2+1,t,goal,goal2); } int query(int x,int h,int t,int goal) { if (h==t) return(data[x]); int mid2=(h+t)/2; if (goal<=mid2) return(query(ls[x],h,mid2,goal)); else return(query(rs[x],mid2+1,t,goal)); } void build(int x,int h,int t) { ph[x]=h; pt[x]=t; if (h==t) return; build(x*2,h,mid); build(x*2+1,mid+1,t); } void insert(int x,int h,int t,int goal) { if (h<=ph[x]&&pt[x]<=t) { ve[x].push_back(goal); return; } if (h<=mid) insert(x*2,h,t,goal); if (mid<t) insert(x*2+1,h,t,goal); } int find(int root,int x) { int y=query(root,1,N,x); if (y==x) return(x); else return(find(root,y)); } void dfs(int x,int h,int t,int ans) { stack<re> s; last[x]=now; int len=ve[x].size(); for (int i=0;i<len;i++) { int x1=a[ve[x][i]].x,x2=a[ve[x][i]].y; int x11=find(now,x1),x22=find(now,x2); if (x11!=x22) { if (count2[x11]>count2[x22]) swap(x11,x22); change(now,now,1,N,x11,x22); s.push(re{x22,count2[x22]}); count2[x22]+=count2[x11]; ans++; } } if (h==t) { if (ans==n-1) ft[h]=1; else ft[h]=0; } else { dfs(x*2,h,(h+t)/2,ans); dfs(x*2+1,(h+t)/2+1,t,ans); } while (!s.empty()) { re x=s.top(); s.pop(); count2[x.x]=x.y; } now=last[x]; } int main() { freopen("noi.in","r",stdin); freopen("noi.out","w",stdout); cin>>n>>m; for (int i=1;i<=m;i++) { cin>>a[i].x>>a[i].y; } cin>>k; for (int i=1;i<=n;i++) f[i]=1; for (int i=1;i<=n;i++) { change(now,now,1,N,i,i); count2[i]=1; } build(1,1,k); for (int i=1;i<=k;i++) { int nown; cin>>nown; for (int j=1;j<=nown;j++) { cin>>b[i][j]; if (i-1>=f[b[i][j]]) { insert(1,f[b[i][j]],i-1,b[i][j]); } f[b[i][j]]=i+1; } } for (int i=1;i<=m;i++) if (f[i]<=k) insert(1,f[i],k,i); dfs(1,1,k,0); for (int i=1;i<=k;i++) if (ft[i]==1) cout<<"Connected"<<endl; else cout<<"Disconnected"<<endl; return 0; }
原文地址:https://www.cnblogs.com/yinwuxiao/p/9038629.html
时间: 2024-11-05 22:55:59