Given n puddings, each of which has a color, changes all the puddings of a color to another color multiple times, and asks the number of color segments
Data range: n <= 10 W color number <= 100 W
The heuristic merge of linked lists 0.0 has never been written clearly. In fact, it is to open a linked list to record the positions of each color. When merging, repeat the short chain to see if there is a long chain color on both sides.
However, switching is troublesome. 0.0 you need to open an array to record the true color of each number. You can switch the two positions of the array.
Pay attention to the use of garbage should not be left in the original size merger, then clear the head merger, and then make it null, or else it will become the gospel of obsessive-compulsive disorder.
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 1001001using namespace std;struct abcd{abcd *next;int pos;}*head[M];int n,m,ans,a[M];int f[M],size[M];inline void Add(int x,int y){abcd *temp=new abcd;temp->pos=y;temp->next=head[x];head[x]=temp;}inline void Merge(int x,int y){abcd *temp;if(x==y)return ;if(size[f[x]]>size[f[y]])swap(f[x],f[y]);x=f[x];y=f[y];if(!head[x])return ;for(temp=head[x];temp;temp=temp->next){if(a[temp->pos-1]==y) --ans;if(a[temp->pos+1]==y) --ans;}for(temp=head[x];temp;temp=temp->next)a[temp->pos]=y;for(temp=head[x];temp->next;temp=temp->next);temp->next=head[y];head[y]=head[x];head[x]=0x0;size[y]+=size[x];size[x]=0;}int main(){int i,p,x,y;cin>>n>>m;for(i=1;i<=n;i++){scanf("%d",&a[i]);if(a[i]!=a[i-1])++ans;Add(a[i],i);f[a[i]]=a[i];size[a[i]]++;}for(i=1;i<=m;i++){scanf("%d",&p);if(p==1){ scanf("%d%d",&x,&y); Merge(x,y);}elseprintf("%d\n",ans);}}
Bzoj 1483 hnoi2009 dream pudding linked list + heuristic merge