BZOJ 4569: [Scoi2016]萌萌哒

来源:互联网 发布:超级神基因优化液txt 编辑:程序博客网 时间:2024/05/15 12:58

妙啊 我好菜啊

将一个要求用ST表分割成logn个要求,如果把f[i][j]f[u][v]在同一个集合,那么f[i][j1]f[u][v1]f[i+2v1][j1]f[u][u+2v1][v1]就并到同一个集合,最后只需要计算f[i][0]不同的集合数cnt,则答案为910cnt1 特判一波n=1就好

#include<bits/stdc++.h>using namespace std;const int N=1e5+2,mod=1e9+7;char B[1<<14],*S=B,*T=B;#define gc (S==T&&(T=(S=B)+fread(B,1,1<<14,stdin),S==T)?-1:*S++)inline int read(){    int x=0,f=1; char ch=gc;    while(ch<'0' || ch>'9'){if(ch=='-')f=-1; ch=gc;}    while(ch>='0' && ch<='9'){x=(x<<1)+(x<<3)+ch-'0'; ch=gc;}    return x*f;}int f[N][17],F[N*17],b[17],px[N*17],py[N*17],tot;bool v[N*17];int fa(int x){return x==F[x]?x:F[x]=fa(F[x]);}void merge(int x,int y){x=fa(x),y=fa(y),F[x]=y;}int main(){    int i,j,n=read(),m=read(); b[0]=1,tot=0;    if(n==1)return puts("0"),0;    for(i=1;i<17;++i) b[i]=b[i-1]<<1;    for(i=1;i<=n;++i)        for(j=0;j<17;++j)            if(i+b[j]-1<=n)f[i][j]=++tot,F[tot]=tot,px[tot]=i,py[tot]=j;            else break;    for(i=1;i<=m;++i){        int l1=read(),r1=read(),l2=read(),r2=read();        for(j=16;~j;--j)            if(l1+b[j]-1<=r1) merge(f[l1][j],f[l2][j]),l1+=b[j],l2+=b[j];    }    for(j=16;j;--j)        for(i=1;i<=n;++i) if(f[i][j]){            int u=fa(f[i][j]),x=px[u];            merge(f[i][j-1],f[x][j-1]);            merge(f[i+b[j-1]][j-1],f[x+b[j-1]][j-1]);        }    int ans=9,c=-1;    for(i=1;i<=n;++i) if( !v[f[i][0]=fa(f[i][0])] )v[f[i][0]]=1,++c;    while(c--)ans=1ll*ans*10%mod;    printf("%d\n",ans);    return 0;}