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