One heuristic merge training

How did no contact before an exam, and quickly to mend

https://www.luogu.org/problem/P3201

analysis:

The same color with a class like former star chain to keep up form

Consider heuristic merger, the combined small to large above

If you want to become x y,

If sz [x] <sz [y], connected directly to the x of y like the above

If sz [x]> sz [y], if connected directly to the x-y color will later becomes x

So we need to use an array of f, means that when we are looking for color x, in fact, need to find a color for f [x] chain. If this is necessary to exchange the exchange upper case f [x] and f [y].

code :

#include<bits/stdc++.h>
#define ll long long
#define il inline
#define ri register int
#define lowbit(x) x&(-x)
using namespace std;
const int maxn=1e6+5;
int head[maxn],nxt[maxn],fir[maxn];
int a[maxn],col[maxn],sz[maxn];
int n,m,ans;
il void merge(int x,int y){
    for(ri i=head[x];i;i=nxt[i]){
        if(a[i-1]==y)ans--;
        if(a[i+1]==y)ans--;
    }
    for(ri i=head[x];i;i=nxt[i])a[i]=y;
    nxt[fir[x]]=head[y];
    head[y]=head[x]; 
    sz[y]+=sz[x];
    head[x]=sz[x]=fir[x]=0;
}
int main(){
    scanf("%d%d",&n,&m);
    for(ri i=1;i<=n;i++){
        scanf("%d",&a[i]);
        if(a[i]!=a[i-1])ans++;
       col[a[i]]=a[i];
       if(!head[a[i]])fir[a[i]]=i;
       sz[a[i]]++;
       nxt[i]=head[a[i]];
       head[a[i]]=i;
    }
    while(m--){
        int op,x,y;
        scanf("%d",&op);
       if(op==1){
        scanf("%d%d",&x,&y);
        if(x==y)continue;
        if(sz[col[x]]>sz[col[y]])swap(col[x],col[y]);
        if(!sz[col[x]])continue;
        merge(col[x],col[y]);
    }
    else printf("%d\n",ans);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/wzxbeliever/p/11864906.html