Heuristic merge linked list:
I'm writing a chain adjacency table that's the type of notation =
Record the color on each node, the same color is crammed into the same linked list, each time you merge two linked lists, you can traverse one of them, if the color of a node and the other linked list of the same will reduce the answer.
Then the time complexity of the list is O (NLOGN) every time if the number of traversed nodes is small.
But because the color of the node is less, it is not necessarily to be dyed off (may dye the color counter). So to record again, when querying a color, is actually to query what color.
1#include <cstdio>2#include <iostream>3#include <cstring>4 using namespacestd;5 Const intmaxn=100233, maxm=1002333;6 intLAST[MAXM],PRE[MAXN];7 intFA[MAXM];8 intMP[MAXN],SM[MAXM];9 inti,j,k,n,m,id,ans,x,y;Ten One intRaCharRx; AInlineintRead () { -Rx=getchar (), ra=0; - while(rx<'0'|| Rx>'9') rx=GetChar (); the while(rx>='0'&&rx<='9') ra*=Ten, ra+=rx- -, Rx=getchar ();returnRA; - } -InlinevoidMergeintXinty) { - if(!sm[x])return; + inti;sm[y]+=sm[x],sm[x]=0; - for(I=last[x];i;i=pre[i]) ans-= (mp[i-1]==y) + (mp[i+1]==y); + for(I=last[x];p re[i];i=pre[i]) mp[i]=y; Amp[i]=y; atpre[i]=last[y],last[y]=last[x],last[x]=0; - } - intMain () { -N=read (), m=read (); - for(i=1; i<=n;i++) Mp[i]=read (), ans+=mp[i]!=mp[i-1],pre[i]=last[mp[i]],last[mp[i]]=i,sm[mp[i]]++,fa[mp[i]]=Mp[i]; - while(m--){ inId=read (); - if(id==2) printf ("%d\n", ans);Else{ toX=read (), y=read (); + if(x==y)Continue; - if(sm[fa[x]]>Sm[fa[y]) swap (fa[x],fa[y]); the merge (Fa[x],fa[y]); * } $ }Panax Notoginseng return 0; -}
View Code
[bzoj1483] [HNOI2009] Dream pudding