牛客练习赛39D

n,m<=5e4;

首先操作2用并查集就行了。题解说的好啊!

考虑操作一,连的两个点如果同色,直接合并,然后这个颜色的联通块-1,然后合并bitset,就是或一下。bitset维护的是相连的异色结点。

如果两个点异色,那么我们就不管他们,直接在两个bitset里分别把对方设为1。

对于操作三 直接 (b[x]&b[y]).count(); 就行了。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int N = 5e4+5;
 4 int fa[N];
 5 bitset<50001> b[N];
 6 int find(int a){
 7     return a==fa[a]?a:fa[a]=find(fa[a]);
 8 }
 9 int n,m,op,x,y,c[N];
10 
11 int main(){
12     ios::sync_with_stdio(false);
13     cin>>n>>m;
14     int hei=0,bai;
15     for(int i=1;i<=n;i++){
16         fa[i]=i;cin>>c[i];
17         hei+=c[i];
18     }
19     bai=n-hei;
20     while (m--){
21         cin>>op;
22         if(op==1){
23             cin>>x>>y;
24             int xx=x,yy=y;
25             x=find(x);y=find(y);
26             if(x==y)continue;
27             if(c[xx]==1){
28                 if(c[yy]==1)fa[y]=x,hei--,b[x]|=b[y];
29                 else b[x][yy]=1,b[y][xx]=1;
30             } else{
31                 if(c[yy]==0)fa[y]=x,bai--,b[x]|=b[y];
32                 else b[x][yy]=1,b[y][xx]=1;
33             }
34         } else if(op==2){
35             cin>>x;
36             if(!x)cout<<bai<<endl;
37             else cout<<hei<<endl;
38         } else{
39             cin>>x>>y;
40             x=find(x);y=find(y);
41             if(x==y)cout<<-1<<endl;
42             else{
43                 cout<<(b[x]&b[y]).count()<<endl;
44             }
45         }
46     }
47 }
View Code

猜你喜欢

转载自www.cnblogs.com/MXang/p/10358693.html