Heuristic merge, merge the smaller siz behind the larger siz when merging
The meaning of the question:
There are two operations
1. Change all x to y
2. Find the color segment of the sequence such as 1 2 2 1 ans=2 (m<=1000000)
First, you can find the ans of the initial sequence, and then each time Modifying a color is equivalent to merging two colors, a heuristic merge.
Heuristic merging is to add the violence of sz small (s1) to sz large (s2), because sz[s1] is at least doubled, and at most doubled totsz, so the complexity is O(logn)
Attached code that is not known to be correct
#include<cstdio> #include<cmath> #include<algorithm> #define maxn 1000010 using namespace std; int n,m,ans,a[maxn],head[maxn],nex[maxn],f[maxn],sz[maxn]; void insert(int col,int wher){ int tmp=head[col];head[col]=wher;nex[wher]=tmp; } void merge(int &x,int &y){ x=f[x];y=f[y]; if(x==y)return; if(sz[x]>sz[y])swap(x,y); if(head[x]==0)return; for(int i=head[x];i;i=nex[i]){ if(a[i+1]==y)ans--; if(a[i-1]==y)ans--; } for(int i=head[x];i;i=nex[i])a[i]=y; int k; for(k=head[y];k;k=nex[k]); nex[k]=head[x];sz[y]+=sz[x];sz[x]=head[x]=0; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); if(a[i]!=a[i-1])ans++; f[a[i]]=a[i];sz[a[i]]++; insert(a[i],i); } while(m--){ int typ; scanf("%d",&typ); if(typ==1){int x,y;merge(x,y);}else printf("%d\n",ans); } }