zoukankan      html  css  js  c++  java
  • 【BZOJ1483】【HNOI2009】梦幻布丁

    题意:n个连续的点,有若干种颜色,每个颜色会因为某些操作变为另一种颜色,动态查询颜色段数。

    解题思路:对每个颜色开一棵平衡树启发式合并应该是最裸的想法,但是我们有更优的!

    考虑对每个颜色利用链表储存它的集合,在合并两种颜色时可以很简单通过对比原节点位置的前后颜色来进行答案的更新,然后利用启发式合并进行保证合并效率即可。

    总复杂度: ( O( q log c ) ) / ( O (c) ) C表示颜色数。(目前是BZOJ Rank2 200ms)

    #include <stdio.h>
    #define MN 100005
    #define MC 1000005
    #define r register
    #define getchar() (S==TT&&(TT=(S=BB)+fread(BB,1,1<<15,stdin),TT==S)?EOF:*S++)
    char BB[1<<15],*S=BB,*TT=BB;
    inline int read(){
        r int x=0;r char c;
        for (;(c=getchar())<'0'||c>'9';);
        for (x=c-'0';(c=getchar())>='0'&&c<='9';x=(x<<3)+(x<<1)+c-'0');
        return x;
    }
    inline void swap(int &a,int &b){a^=b^=a^=b;}
    int rt[MC],nxt[MN],s[MC],col[MN],n,q,ans;
    inline void merge(int x,int y){
        if (s[x]>s[y]){swap(x,y);}
        for (r int i=rt[x]; i; i=nxt[i]){
            ans-=(col[i-1]==y)+(col[i+1]==y);
            if (!nxt[i]){nxt[i]=rt[y];break;}
        }for (r int i=rt[x]; i!=rt[y]; i=nxt[i]) col[i]=y;
        rt[y]=rt[x];s[y]+=s[x];s[x]=rt[x]=0; 
    }
    void init(){
        n=read(),q=read();ans=1;
        for (int i=1; i<=n; ++i) col[i]=read(),nxt[i]=rt[col[i]],rt[col[i]]=i;
        for (r int i=2; i<=n; ++i) if (col[i]!=col[i-1]) ++ans;
    }
    void solve(){
        while(q--){
            r int op=read();
            if (op==1){r int x=read(),y=read();if (x!=y) merge(x,y);}
            else printf("%d
    ",ans);
        }
    }
    int main(){init();solve();return 0;}
  • 相关阅读:
    Webpack
    django 基础入门(二)
    django 基础入门(一)
    jQuery(二)
    JavaScripts+jquery
    html(第一天,div+css)
    SqlAlchemy ORM
    redis总结
    memcached总结
    Python (九) 协程以及数据库操作
  • 原文地址:https://www.cnblogs.com/Melacau/p/BZOJ1483.html
Copyright © 2011-2022 走看看