bzoj1483

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);
    }
}

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325339803&siteId=291194637