zoukankan      html  css  js  c++  java
  • luogu3295 萌萌哒 (并查集+ST表)

    如果给相同的位置连边,最后联通块数是n,最后答案就是$9*10^{n-1}$

    但直接连边是$O(n^2)$的

    所以事先处理出一个ST表,每次O(1)地给那个ST表连边

    最后再一点一点下放,就是把在这层的同一集合的的左儿子连到一个里,右儿子连到一个里

    统计最下面那一层的联通块数量就行了

     1 #include<bits/stdc++.h>
     2 #define pa pair<int,int>
     3 #define CLR(a,x) memset(a,x,sizeof(a))
     4 using namespace std;
     5 typedef long long ll;
     6 const int maxn=1e5+10,logn=20,P=1e9+7;
     7 
     8 inline ll rd(){
     9     ll x=0;char c=getchar();int neg=1;
    10     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
    11     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
    12     return x*neg;
    13 }
    14 
    15 int id[maxn][20],pct,fa[maxn*logn],ch[maxn*logn][2];
    16 int N,M;
    17 bool flag[maxn*logn];
    18 
    19 inline int getf(int x){return fa[x]==x?x:fa[x]=getf(fa[x]);}
    20 inline void makest(){
    21     for(int i=N;i;i--){
    22         id[i][0]=++pct;
    23         for(int j=0;id[i][j]&&id[i+(1<<j)][j];j++){
    24             id[i][j+1]=++pct;
    25             ch[id[i][j+1]][0]=id[i][j];
    26             ch[id[i][j+1]][1]=id[i+(1<<j)][j];
    27         }
    28         // printf("%d %d
    ",i,id[i][0]);
    29     }
    30     for(int i=1;i<=pct;i++) fa[i]=i;
    31 }
    32 
    33 inline pa get(int l,int r){
    34     int x=log2(r-l+1);
    35     return make_pair(id[l][x],id[r-(1<<x)+1][x]);
    36 }
    37 
    38 inline void add(int a,int b){
    39     int x=getf(a),y=getf(b);if(x==y) return;
    40     fa[x]=y;
    41 }
    42 
    43 int main(){
    44     //freopen("","r",stdin);
    45     int i,j,k;
    46     N=rd(),M=rd();
    47     makest();
    48     for(i=1;i<=M;i++){
    49         int l1=rd(),r1=rd(),l2=rd(),r2=rd();
    50         pa a=get(l1,r1),b=get(l2,r2);
    51         add(a.first,b.first);add(a.second,b.second);
    52     }
    53     for(i=17;i;i--){
    54         for(j=1;j<=N&&id[j][i];j++){
    55             // printf("%d %d %d %d
    ",j,i,id[j][i],fa[id[j][i]]);
    56             if(id[j][i]!=fa[id[j][i]]){
    57                 add(ch[id[j][i]][0],ch[fa[id[j][i]]][0]);
    58                 add(ch[id[j][i]][1],ch[fa[id[j][i]]][1]);
    59             }
    60         }
    61     }
    62     int cnt=0;
    63     for(i=1;i<=N;i++){
    64         if(!flag[getf(id[i][0])]) cnt++,flag[getf(id[i][0])]=1;
    65     }
    66     
    67     ll ans=9;
    68     for(i=1;i<=cnt-1;i++) ans=(ans*10)%P;
    69     printf("%d
    ",ans);
    70     return 0;
    71 }
  • 相关阅读:
    vuejs中使用echart图表
    锚点链接
    如何动态修改网页的标题(title)?
    如何为图片添加热点链接?(map + area)
    cookie
    如何为你的网站添加标志性的图标(头像)呢?
    图片拖拽上传至服务器
    js定时器之setTimeout的使用
    input[type=file]中使用ajaxSubmit来图片上传
    input[type=file]样式更改以及图片上传预览
  • 原文地址:https://www.cnblogs.com/Ressed/p/9782234.html
Copyright © 2011-2022 走看看