zoukankan      html  css  js  c++  java
  • P3201 [HNOI2009]梦幻布丁 启发式合并

      

    用启发式合并来做  复杂度为nlong

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    //////////////////////////////////
    const int N=2e6+10;
    
    int head[N],siz[N],pos,c[N],f[N],st[N],ans,n,m;
    int nex[N];
    struct Edge{int to,nex;}edge[N<<1];
    void add(int a,int b){edge[++pos]=(Edge){b,head[a]};head[a]=pos;}
    
    int Merge(int x,int y)
    {
        for(int i=head[x];i;i=edge[i].nex)
        {
            int v=edge[i].to;
            ans-=(y==c[v-1])+(y==c[v+1]);
        }
        for(int i=head[x];i;i=edge[i].nex)c[edge[i].to]=y;
        edge[st[x]].nex=head[y];head[y]=head[x];siz[y]+=siz[x];
        head[x]=siz[x]=st[x]=0;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        rep(i,1,n)
        {
            scanf("%d",&c[i]);f[c[i]]=c[i];
            ans+=c[i]!=c[i-1];
            if(!head[c[i]])st[c[i]]=pos+1;
            siz[c[i]]++;add(c[i],i);
        }
        while(m--)
        {
            int op;scanf("%d",&op);
            if(op==2)printf("%d
    ",ans);
            else
            {
                int x,y;scanf("%d%d",&x,&y);
                if(x==y)continue;
                if(siz[f[x]]>siz[f[y]])swap(f[x],f[y]);
                if(!siz[f[x]])continue;
                Merge(f[x],f[y]);
            }
        }
    }
    View Code
  • 相关阅读:
    批量修改图片尺寸
    批量修改文件名
    C++ 字符串的编码
    Hanoi问题
    农夫过河问题
    遍历文件夹中所有图片
    仿射变换和透射变换
    程序局部性原理
    14年年底的学习计划
    linux之Vim使用
  • 原文地址:https://www.cnblogs.com/bxd123/p/11422542.html
Copyright © 2011-2022 走看看