什么是启发式合并?
题目
int a[N], n, m;
int fcol[N];
vector<int> st[N];
int ans = 0;
void Merge(int x,int y){ // x -> y
// upd ans
for(int i :st[x]){
if(a[i-1]==y)
ans--;
if(a[i+1]==y)
ans--;
}
// upd 数组
for(int i:st[x]){
a[i] = y;
}
// upd st
for(int i:st[x]){
st[y].push_back(i);
}
st[x].clear();
}
void sov(){
cin >> n >> m;
for (int i = 1; i <= n;i++){
cin >> a[i];
if(a[i]!=a[i-1])
ans++;
fcol[a[i]] = a[i];
st[a[i]].push_back(i);
}
for (int i = 1; i <= m;i++){
int op;
cin >> op;
if(op==2){
cout << ans << endl;
}else{
int x, y;
cin >> x >> y;
if(x==y)
continue;
if(st[fcol[x]].size()>st[fcol[y]].size()){
swap(fcol[x], fcol[y]);
}
Merge(fcol[x], fcol[y]);
}
}
}
小tip:我们用 fcol[N] 来 表示 颜色的映射(实际颜色),应为我们在 合并的 时候 要始终 让 小的颜色集合 丢 到 大的颜色集合里面
如果 x->y 是, x的集合更大怎么办呢 ? 那我们就让两个颜色(实际颜色)互换 一下(映射swap一下)