zoukankan      html  css  js  c++  java
  • [BZOJ4569] [Scoi2016]萌萌哒

    [BZOJ4569][Scoi2016]萌萌哒

    好题!

    倍增维护并查集合并

    一个倍增数组\(fa[i][j]\)维护从\(i\)开始长度为\(2^j\)的这一段与那一段长度相同的并在一起

    将两端区间\(l1,r2,l2,r2\)用倍增剖开,在那一层的倍增数组上用并查集合并

    最后每次将\(fa[i][j]\)\(fa[i][j-1],fa[i+(1<<(j-1))][j-1]\)递推即可

    int n,m;
    struct UFS{
        int fa[N];
        int Find(int x) { return fa[x]==x?x:fa[x]=Find(fa[x]); }
        void init(){ rep(i,1,n) fa[i]=i; }
        void merge(int x,int y) { 
            fa[Find(x)]=Find(y);
        }
    } B[18];
    int LOG;
    int main(){
        n=rd(),m=rd();
        for(LOG=0;(1<<LOG)<=n;LOG++) B[LOG].init();
        LOG--;
        rep(i,1,m) {
            int l1=rd(),r1=rd();
            int l2=rd();rd();
            if(l1==l2) continue;
            int len=r1-l1+1;
            drep(j,LOG,0) {
                if(len>=(1<<j)) {
                    B[j].merge(l1,l2);
                    l1+=1<<j,l2+=1<<j;
                    len-=1<<j;
                }
            }
        }
        drep(i,LOG,1) {
            int len=(1<<(i-1));
            rep(j,1,n) {
                int f=B[i].Find(j);
                B[i-1].merge(j,f);
                B[i-1].merge(j+len,f+len);
            }
        }
        int cnt=0;
        rep(i,1,n) if(B[0].Find(i)==i) cnt++;
        ll ans=1;
        rep(i,1,cnt-1) ans=ans*10%P;
        ans=ans*9%P;
        printf("%lld\n",ans);
    }
    
    
  • 相关阅读:
    树上莫队学习笔记
    点分治学习笔记
    7.11总结
    线段树合并学习笔记
    7.10总结
    bzoj1201: [HNOI2005]数三角形----递推+bitset
    bitset(01串)优化
    Tarjan系列1
    bsgs(Baby Steps Giant Steps)算法
    [SD2015]序列统计——solution
  • 原文地址:https://www.cnblogs.com/chasedeath/p/11719899.html
Copyright © 2011-2022 走看看