CODE:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
using namespace std;
struct List{
List *next;
int pos;
List(int _ = 0) {
next = NULL;
pos = _;
}
}*head[MAX];
int cnt,asks;
int src[MAX];
int now,num[MAX];
int C[MAX];
void Pretreatment()
{
for(int i = 1; i < MAX; ++i)
C[i] = i;
}
inline void Add(int col,int pos)
{
List *temp = new List(pos);
temp->next = head[col];
head[col] = temp;
}
inline void Change(int from,int aim)
{
if(from == aim) return ;
if(num[C[from]] > num[C[aim]])
swap(C[from],C[aim]);
from = C[from],aim = C[aim];
if(head[from] == NULL) return ;
for(List *x = head[from]; x != NULL; x = x->next) {
if(src[x->pos - 1] == aim) --now;
if(src[x->pos + 1] == aim) --now;
Add(aim,x->pos);
}
for(List *x = head[from]; x != NULL; x = x->next)
src[x->pos] = aim;
static List *stack[MAX];
int top = 0;
for(List *x = head[from]; x != NULL; x = x->next)
stack[++top] = x;
while(top) delete stack[top--];
head[from] = NULL;
num[aim] += num[from];
num[from] = 0;
}
int main()
{
Pretreatment();
cin >> cnt >> asks;
int last = 0;
for(int i = 1; i <= cnt; ++i) {
scanf("%d",&src[i]);
Add(src[i],i);
++num[src[i]];
if(src[i] != last) {
last = src[i];
++now;
}
}
for(int flag,x,y,i = 1; i <= asks; ++i) {
scanf("%d",&flag);
if(flag == 1) {
scanf("%d%d",&x,&y);
Change(x,y);
}
else printf("%d\n",now);
}
return 0;
}BZOJ 1483 HNOI 2009 梦幻布丁 链表+启发式合并
原文地址:http://blog.csdn.net/jiangyuze831/article/details/41577521