zoukankan      html  css  js  c++  java
  • bzoj1483: [HNOI2009]梦幻布丁

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 using namespace std;
     6 #define maxn 1000005
     7 int n,m,ans,fa[maxn],color[maxn],st[maxn],now[maxn],prep[maxn],size[maxn];
     8 void read(int &x){
     9     x=0; int f=1; char ch;
    10     for (ch=getchar();!isdigit(ch);ch=getchar()) if (ch=='-') f=-1;
    11     for (;isdigit(ch);ch=getchar()) x=x*10+ch-'0'; x*=f;
    12 }
    13 void merge(int x,int y){
    14     if (size[fa[x]]>size[fa[y]]) swap(fa[x],fa[y]);
    15     if (size[fa[x]]==0) return;
    16     x=fa[x],y=fa[y];
    17     for (int i=now[x];i;i=prep[i]){
    18         if (color[i-1]==y) ans--;
    19         if (color[i+1]==y) ans--;
    20     }
    21     for (int i=now[x];i;i=prep[i]) color[i]=y;
    22     size[y]+=size[x],size[x]=0;
    23     prep[st[x]]=now[y],now[y]=now[x]; now[x]=st[x]=size[x]=0;
    24 }
    25 int main(){
    26     read(n),read(m); ans=0;
    27     for (int i=1;i<=n;i++){
    28         read(color[i]); size[color[i]]++,fa[color[i]]=color[i];
    29         if (color[i]!=color[i-1]) ans++;
    30         if (!st[color[i]]) st[color[i]]=i;
    31         prep[i]=now[color[i]],now[color[i]]=i;
    32     }
    33     for (int type,x,y;m;--m){
    34         read(type);
    35         if (type==2) printf("%d
    ",ans);
    36         else{
    37             read(x),read(y);if (x==y) continue;
    38             merge(x,y);
    39         }
    40     }
    41     return 0;
    42 }
    View Code

    题目大意:N个布丁摆成一行,进行M次操作.每次将某个颜色的布丁全部变成另一种颜色的,然后再询问当前一共有多少段颜色.例如颜色分别为1,2,2,1的四个布丁一共有3段颜色.

     做法:我们考虑链表的启发式合并,每次我们把数量少的往数量大的合并即可,还要注意,每次小的往的合并时可能会导致有些颜色应该有而链表中却没有了,所以我们需要记录每种颜色在链表中实际上是什么颜色。为了保证链表合并的复杂度,我们对每条链记录首尾端点,链表的合并就是O(1)了,而颜色的修改均摊是logn的,所以总复杂度为O(mlogn)。

    链表+启发式合并。

  • 相关阅读:
    AJAX 大全
    has value '1.8', but '1.7' is required
    VS2010官方下载地址
    win10桌面显示我的电脑
    使用 CAST
    for循环+canvas实现黑客帝国矩形阵
    C# Lambda
    win7系统部分便笺的元数据已被损坏怎么恢复
    SQL查询所有表,所有列
    truncate和delete之间有什么区别
  • 原文地址:https://www.cnblogs.com/OYzx/p/5617583.html
Copyright © 2011-2022 走看看