维护带权并查集

大概叫这个名字吧
https://atcoder.jp/contests/abc380/tasks/abc380_e

#include<bits/stdc++.h>
#define endl '\n'
#define lowbit(x) (x&-x)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
const double pi=acos(-1);
const int N=5e5+5;
int fa[N],col[N],col_num[N];
int cnt[N],l[N],r[N];//l数组为左边界,r数组为右边界,cnt数组指某一集合点的数量

int find(int x){
    if(fa[x]==x) return x;
    else return fa[x]=find(fa[x]);
}

void un(int u,int v){
    int ufa=find(u);
    int vfa=find(v);

    fa[ufa]=vfa;
    l[vfa]=min(l[ufa],l[vfa]);
    r[vfa]=max(r[ufa],r[vfa]);

    cnt[vfa]+=cnt[ufa];
}

void draw(int x,int c){
    int xfa=find(x);
    col_num[col[xfa]]-=cnt[xfa];
    col[xfa]=c;
    col_num[c]+=cnt[xfa];
}


void solve(){
    int n,q;cin>>n>>q;

    for(int i=1;i<=n;i++){
        fa[i]=col[i]=l[i]=r[i]=i;
        col_num[i]=1;
        cnt[i]=1;
    }

    while(q--){
        int op;cin>>op;
        if(op==1){
            int x,c;cin>>x>>c;
            draw(x,c);
            int L=l[find(x)];
            int R=r[find(x)];

            if(col[find(L-1)]==c) un(L-1,x);
            if(col[find(R+1)]==c) un(R+1,x);

        }
        else if(op==2){
            int c;cin>>c;
            cout<<col_num[c]<<endl;
        }
    }
}

signed main(){
    ios::sync_with_stdio(false);cin.tie(nullptr);
    int t=1;
    //cin>>t;
    while(t--) solve();
    return 0;
}

posted on 2024-11-25 21:34  TaopiTTT  阅读(2)  评论(0编辑  收藏  举报