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
  • 相关阅读:
    spi详解
    spi协议
    C语言break,return
    通信协议
    传输层
    网络层
    数据链路层
    物理层
    无线通信
    cpu设计过程
  • 原文地址:https://www.cnblogs.com/czllgzmzl/p/5301515.html
Copyright © 2011-2022 走看看