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

    4569: [Scoi2016]萌萌哒

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 1554  Solved: 791
    [Submit][Status][Discuss]

    Description

    一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条
    件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1+1Sl1+2...Sr1与Sl2Sl2+1Sl2+2...S
    r2完全相同。比如n=6时,某限制条件l1=1,r1=3,l2=4,r2=6,那么123123,351351均满足条件,但是12012,13
    1141不满足条件,前者数的长度不为6,后者第二位与第五位不同。问满足以上所有条件的数有多少个。

    Input

    第一行两个数n和m,分别表示大数的长度,以及限制条件的个数。接下来m行,对于第i行,有4个数li1,ri1,li2
    ,ri2,分别表示该限制条件对应的两个区间。
    1≤n≤10^5,1≤m≤10^5,1≤li1,ri1,li2,ri2≤n;并且保证ri1-li1=ri2-li2。

    Output

     一个数,表示满足所有条件且长度为n的大数的个数,答案可能很大,因此输出答案模10^9+7的结果即可。

    Sample Input

    4 2
    1 2 3 4
    3 3 3 3

    Sample Output

    90

    HINT

    Source

    Solution

    妙题。

    维护相等关系怎么办?

    各种匹配都用不上。

    感到无从下手。

    我们就不考虑区间相等的问题了。

    转化研究对象,

    区间相等本质上是点的对应相等。

    而一些点的位置都要相等的话,那么只能取同样的一个值。具体是哪个值没有关系。(当然不能前导零)

    维护相等关系,用并查集。

    所以,我们可以枚举所有的位置,每个位置开始是一个联通块。

    再对每一个位置枚举所有条件,然后合并。答案就是9*10^(num-1) num为联通块的个数。

    O(n^2)

    这样合并太暴力了。

    但是最后的查询只有O(n)

    我们考虑均衡到O(nlogn)

    一个浪费的地方在于,我们每个点要枚举所有的询问,其实这个询问是一个区间相等的关系。

    能不能直接把区间相等直接用并查集并起来呢?

    灵活的拆分区间,

    可以比较自然地想到倍增。

    所以,我们也可以把并查集利用倍增来进行实现。

    把每个位置拆成logn个点。

    第i个点,表示,x开始,连续2^i的子串。

    两个条件相等,就二进制拆分成logn个区间,然后对应的并查集合并。

    O(nlogn询问)

    最后查询答案呢?

    如果知道最后的每个点的相等关系就容易处理了。

    我们可以拆分并查集。

    2^N=2^(N-1)+2^(N-1)

    从大到小枚举所有的nlogn个并查集点。

    对于并查集的点k,把k的父亲找出来,自己和父亲代表的区间都拆成两半,前后部分分别再并起来。

    复杂度O(nlogn)

    其实,我们就是用倍增拆点的并查集维护了区间相等关系。

    可以比较快地拆分区间,最后的并查集拆分复杂度也有保证。

    其实感觉挺类似线段树的(虽然线段树不是二进制拆分)

    都是把区间拆分。

    用大的区间合并而不再往下分,就类似线段树的懒标记。

    最后到叶子,就是懒标记下放。

    update:2018.12.8

    更具体地来考虑复杂度为什么变优秀了:

    最后一共其实就是一棵并查集树,每个点只有一个father

    但是期间每次枚举区间的O(n^2)的话,平均每个点要规定O(n)次father,其实最后就只需要一个。

    这种倍增并查集的方式,本质上对这些关系进行了压缩。只有O(logn)个了。

    通过合并冗余的关系,减少过程中的关系调整次数,就得到了优秀的复杂度。

    (其实懒标记也是这样的)

    代码:

    #include<bits/stdc++.h>
    #define reg register int
    #define il inline
    #define numb (ch^'0')
    #define num(x,y) (y*n+x)
    using namespace std;
    typedef long long ll;
    il void rd(int &x){
        char ch;x=0;bool fl=false;
        while(!isdigit(ch=getchar()))(ch=='-')&&(fl=true);
        for(x=numb;isdigit(ch=getchar());x=x*10+numb);
        (fl==true)&&(x=-x);
    }
    namespace Miracle{
    const int N=1e5+5;
    const int mod=1e9+7;
    int n,m;
    int fa[N*20];
    bool buc[N];
    int fin(int x){
        return fa[x]==x?x:fa[x]=fin(fa[x]);    
    }
    void merge(int x,int y){
        int k1=fin(x),k2=fin(y);
        if(k1!=k2) fa[k1]=k2;
    }
    int main(){
        rd(n);rd(m);
        for(reg i=1;i<=n*20;++i) fa[i]=i;
        int l1,r1,l2,r2;
        for(reg i=1;i<=m;++i){
            rd(l1);rd(r1);rd(l2);rd(r2);
            int len=r1-l1+1;
            for(reg j=19;j>=0;--j){
                if(len>=(1<<j)){
                    merge(num(l1,j),num(l2,j));
                    l1+=(1<<j),l2+=(1<<j);
                    len-=(1<<j);
                }
            }
        }
        for(reg j=19;j>=1;--j){
            for(reg i=1;i<=n;++i){
                if(i+(1<<j)-1>n) break;
                int to=fin(num(i,j));
                merge(num(i,(j-1)),to-n);
                merge(num(i+(1<<(j-1)),(j-1)),to-n+(1<<(j-1)));    
            }
        }
        ll ans=9;
        ll cnt=0;
        for(reg i=1;i<=n;++i){
            int k=fin(num(i,0));
            if(!buc[k]) buc[k]=1,++cnt;
        }
        for(reg i=1;i<=cnt-1;++i){
            ans=(ans*10)%mod;
        }
        printf("%lld",ans);
        return 0;
    }
    
    }
    int main(){
        Miracle::main();
        return 0;
    }
    
    /*
       Author: *Miracle*
       Date: 2018/12/8 15:01:18
    */
  • 相关阅读:
    如何了解网络链路的性能,吞吐量测试
    Struts+Spring+HibernateSSH整合实例
    在百度贴吧打出被和谐的字和特殊字符:比如繁体字
    SVN 小记
    SVN 小记
    SVN needslock 设置强制只读属性
    在百度贴吧打出被和谐的字和特殊字符:比如繁体字
    TortoiseSVN与Subversion 1.5
    .NET中非对称加密RSA算法的密钥保存
    SVN needslock 设置强制只读属性
  • 原文地址:https://www.cnblogs.com/Miracevin/p/9873655.html
Copyright © 2011-2022 走看看