1#include <iostream>2#include <cstdio>3#include <algorithm>4#include <cstring>5 using namespacestd;6 #defineMAXN 10000057 intN,M,ANS,FA[MAXN],COLOR[MAXN],ST[MAXN],NOW[MAXN],PREP[MAXN],SIZE[MAXN];8 voidReadint&x) {9x=0;intf=1;Charch;Ten for(Ch=getchar ();! IsDigit (CH); Ch=getchar ())if(ch=='-') f=-1; One for(; isdigit (ch); Ch=getchar ()) x=x*Ten+ch-'0'; x*=F; A } - voidMergeintXinty) { - if(size[fa[x]]>Size[fa[y]) swap (fa[x],fa[y]); the if(size[fa[x]]==0)return; -x=fa[x],y=Fa[y]; - for(intI=now[x];i;i=Prep[i]) { - if(color[i-1]==y) ans--; + if(color[i+1]==y) ans--; - } + for(intI=now[x];i;i=prep[i]) color[i]=y; Asize[y]+=size[x],size[x]=0; atPREP[ST[X]]=NOW[Y],NOW[Y]=NOW[X]; now[x]=st[x]=size[x]=0; - } - intMain () { -Read (n), read (m); ans=0; - for(intI=1; i<=n;i++){ -Read (Color[i]); size[color[i]]++,fa[color[i]]=Color[i]; in if(color[i]!=color[i-1]) ans++; - if(!st[color[i]]) st[color[i]]=i; toprep[i]=now[color[i]],now[color[i]]=i; + } - for(inttype,x,y;m;--m) { the read (type); * if(type==2) printf ("%d\n", ans); $ Else{Panax NotoginsengRead (x), read (y);if(x==y)Continue; - merge (x, y); the } + } A return 0; the}
View Code
The main idea: n Pudding in a row, for M operations. Each time a color pudding is turned into a different color, then ask the current number of colors. For example, four puddings with a color of 1,2,2,1 have a total of 3 colors.
Practice: We consider the chain list of heuristic merging, each time we put a small number of a large number of mergers, but also note that each time the smaller to the merger may cause some colors should have and the list is not, so we need to record each color in the list is actually what color. In order to ensure the complexity of the chain list, we record the end of each chain, the link list is O (1), and the color modification is LOGN, so the total complexity is O (MLOGN).
Linked list + heuristic merge.
bzoj1483: [HNOI2009] Fantasy pudding