[SCOI2016]萌萌哒

博客食用更佳bossbaby's blog

思路

并查集

每次使两位相同,相当于在计数时把两个位当成一位来算
所以我们可以用并查集,在每次操作时把两个位用并查集并在一起,查找时用,设最后集合个数为M
那么答案是\(9*(M-1)^{10}\)
因为和1并在一起的数只有9种选择(首位不为0)
但是这样的话复杂度最大是\(O(10^{10})(n,m<=10^5)\)
所以不行

线段树

于是我们考虑线段树的区间操作
可惜不行...

倍增(st表)

另外一种区间操作就是st表
\(st[i][j]\)储存从\(i\)开始往后\(2^j\)的区间
那么就用并查集来判断每个区间的连通性,
每次合并时就用2进制从大到小分成区间合并
比如从\(l_1\)开始的23个数
就分成\(st[l_1][4],st[l_1][2],st[l_1][1],st[l_1][0]\)
分别与\(st[l_2][4],st[l_2][2],st[l_2][1],st[l_2][0]\)合并
最后再把每个区间下放到它的一半这两个区间,最后下放到\(st[i][0]\)就可以统计了

代码

#include<bits/stdc++.h>
#define N 100010
#define P 1000000007
using namespace std;
int st[N][20],fa[N*18],cnt=0,s[N*18];
int n,m;
int find(int x){
    if(x!=fa[x])fa[x]=find(fa[x]);
    return fa[x];
}
void unionn(int x,int y,int k){
    int r1=find(st[x][k]),r2=find(st[y][k]);
    if(r1>r2)swap(r1,r2),swap(x,y);
    fa[r2]=r1;
    find(y);
}//并查集
template<typename T>void read(T&x){
    x=0;
    char c=getchar();
    while(!isdigit(c))c=getchar();
    while(isdigit(c))x=x*10+c-'0',c=getchar();
}//快读
template<typename T>void write (const T x){
    if(x<0){
        putchar('-');
        return write(-x);	
    }
    if(x>9)write(x/10);
    putchar(x%10+'0');
}//快写
int main(){
    read(n);read(m);
    if(n==1){
        write(10);return 0;
    }
    for(int j=0;j<=18;j++)
        for(int i=1;i+(1<<j)-1<=n;i++)
            st[i][j]=++cnt,s[cnt]=i,fa[cnt]=cnt;
    for(int i=1;i<=m;i++){
        int l1,r1,l2,r2;
        read(l1),read(r1),read(l2),read(r2);
        for(int j=18;j>=0;j--){
            if(l1+(1<<j)-1<=r1){
                unionn(l1,l2,j);
                l1+=(1<<j);
                l2+=(1<<j);
            }
        }
    }//二进制拆分并合并
    for(int j=18;j>=1;j--){
        for(int i=1;i+(1<<j)-1<=n;i++){
            int f=find(st[i][j]),sta=s[f];
            if(sta==i)continue;
            unionn(i,sta,j-1);
            unionn(i+(1<<(j-1)),sta+(1<<(j-1)),j-1);
        }
    }//分成两半最后拆成st[i][0]
    long long ans=9;
    for(int i=2;i<=n;i++)
        if(fa[st[i][0]]==st[i][0])ans=(1LL*ans*10)%P;//统计
    write(ans);
}
posted @ 2019-05-30 20:27  bossbaby  阅读(173)  评论(0编辑  收藏  举报