どのようにMENDに迅速に試験前には接触しなかった、と
https://www.luogu.org/problem/P3201
分析:
クラスと同じ色にするかつてのスターチェーンのような形を維持
考えるヒューリスティック合併を、上記大に小さい組み合わせ
あなたは、xのyになりたい場合は、
SZ [X] <SZ [y]は、上記のようにYのXに直接接続されている場合
SZなら[X]> SZ [Y]、X-Y色に直接接続されている場合は、後にXになるであろう
我々は、Fの配列を使用する必要があるので、我々はカラーXを探しているとき、手段が、実際には、必要がf [x]のチェーンの色を見つけるためにすることを。この交換大文字Fを交換する必要がある場合、[X]およびF [Y]。
コード:
#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;
}