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

      启发式合并链表。。

      我写的是链式邻接表那种写法= =

      记录下每个节点上的颜色,颜色相同的就塞进同一个链表,每次合并两个链表的时候,就遍历其中一个,如果某节点两边颜色和另一个链表的相同就减一下答案。

      然后每次如果遍历节点数少的那个链表时间复杂度就是O(nlogn)的了。。

      但因为节点数少的那种颜色不一定是要被染掉的(可能把颜色染反)。。所以要再记录一下,查询某个颜色的时候,实际上是要查询什么颜色。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 using namespace std;
     5 const int maxn=100233,maxm=1002333;
     6 int last[maxm],pre[maxn];
     7 int fa[maxm];
     8 int mp[maxn],sm[maxm];
     9 int i,j,k,n,m,id,ans,x,y;
    10  
    11 int ra;char rx;
    12 inline int read(){
    13     rx=getchar(),ra=0;
    14     while(rx<'0'||rx>'9')rx=getchar();
    15     while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra;
    16 }
    17 inline void merge(int x,int y){
    18     if(!sm[x])return;
    19     int i;sm[y]+=sm[x],sm[x]=0;
    20     for(i=last[x];i;i=pre[i])ans-=(mp[i-1]==y)+(mp[i+1]==y);
    21     for(i=last[x];pre[i];i=pre[i])mp[i]=y;
    22     mp[i]=y;
    23     pre[i]=last[y],last[y]=last[x],last[x]=0;
    24 }
    25 int main(){
    26     n=read(),m=read();
    27     for(i=1;i<=n;i++)mp[i]=read(),ans+=mp[i]!=mp[i-1],pre[i]=last[mp[i]],last[mp[i]]=i,sm[mp[i]]++,fa[mp[i]]=mp[i];
    28     while(m--){
    29         id=read();
    30         if(id==2)printf("%d
    ",ans);else{
    31             x=read(),y=read();
    32             if(x==y)continue;
    33             if(sm[fa[x]]>sm[fa[y]])swap(fa[x],fa[y]);
    34             merge(fa[x],fa[y]);
    35         }
    36     }
    37     return 0;
    38 }
    View Code
  • 相关阅读:
    centos 6.4 FTP安装和配置
    常用正则表达式集锦
    同一服务器部署多个tomcat时的端口号修改详情
    介绍linux下vi命令的使用
    CentOS下安装两个或多个Tomcat7
    tomcat解析之简单web服务器(图)
    吻你
    用C++语言开发Android程序 配置开发环境
    内地开源镜像网站
    Android SDK Android NDK Android Studio 官方下载地址
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5301515.html
Copyright © 2011-2022 走看看