• P3295 [SCOI2016]萌萌哒


    题目传送门

    https://www.luogu.com.cn/problem/P3295

    分析

    我们用ST表,f[i,j]表示[i,i+2^j-1]这一段。

    那么初始时每一段单独成一个集合。

    对于一个限制可以拆成log 份,然后进行集合合并。

    然后呢,如果任意ST[s,t]和ST[i,j]属于同一集合,那么ST[s,t-1]与ST[i,j-1]以及ST[s+2^(t-1)-1,t-1]和f[i+2^(j-1)-1,j-1]都应该属于同一集合。

    为了满足这个限制,只要最后再一层一层的做,把下一层的合并了即可。

    合并注意必须让编号大的合进编号小的里。

    答案就很容易搞出来,也就是9*10^(集合个数-1)。

    代码

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
     
    const int maxn=1e5+10,maxm=20;
    const int mod=1e9+7;
     
    int n,m,l1,l2,r1,r2,cnt=0;
    int fa[maxn*maxm],S[maxn][maxm],sta[maxn*maxm];
     
    int Find(int x) {
        if(fa[x]==x)
            return x;
        return fa[x]=Find(fa[x]);
    }
     
    void merge(int l1,int l2,int k){
        int x=Find(S[l1][k]);
        int y=Find(S[l2][k]);
        if(x>y)
            swap(x,y);
        fa[y]=x;
    }
     
    int main() {
        scanf("%d%d",&n,&m);
        if(n==1)
            printf("10
    ");
        else {
            for(int j=0;j<=maxm;j++)
                for(int i=1;i+(1<<j)-1<=n;i++){
                    S[i][j]=++cnt;
                    sta[cnt]=i;
                    fa[cnt]=cnt;
                }
            for(int i=1;i<=m;i++){
                scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
                for(int j=maxm; j>=0; j--)
                    if(l1+(1<<j)-1<=r1){
                        merge(l1,l2,j);
                        l1+=(1<<j);
                        l2+=(1<<j);
                    }
            }
            for(int j=maxm;j>=1;j--)
                for(int i=1;i+(1<<j)-1<=n;i++){
                    int f=Find(S[i][j]);
                    int s=sta[f];
                    merge(i,s,j-1);
                    merge(i+(1<<j-1),s+(1<<j-1),j-1);
                }
            int ans=9;
            for(int i=2;i<=n;i++)
                if(fa[S[i][0]]==S[i][0])
                    ans=(long long)ans*10%mod;
            printf("%d
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    BZOJ4039 : 集会
    BZOJ3655 : 神经错乱数
    World Finals 2017爆OJ记
    Petrozavodsk Summer-2016. Ural FU Dandelion Contest
    XVII Open Cup named after E.V. Pankratiev. Grand Prix of America (NAIPC-2017)
    递归的逻辑(3)——递归与分治
    递归的逻辑(2)——特征方程和递归算法
    递归的逻辑(1)——递归关系模型
    整数的故事(4)——Karastuba算法
    整数的故事(3)——最小公倍数与哥德巴赫猜想
  • 原文地址:https://www.cnblogs.com/Vocanda/p/12826971.html
Copyright © 2020-2023  润新知