萌萌哒scoi2016
[萌萌哒](https://www.luogu.org/problem/P3295)
1.我们假设每次l1=r1,l2=r1;
即每次得到两个数相同的条件
最后通过并查集,我们可以得到x个块,方案数 9*(10ˆ(x-1));
然后,想一想st表,通过合并 每一层的块,并且在最后释放高层合并,将每个数合并到对应集合里
#include<bits/stdc++.h> #define re return #define dec(i,l,r) for(int i=l;i>=r;--i) #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } int n,m,mod=1000000007; int fa[100005][21],id[100005][21]; inline int find(int x,int k) { re fa[x][k]==x?x:fa[x][k]=find(fa[x][k],k); } inline void merge(int x,int y,int k) { int f1=find(fa[x][k],k); int f2=find(fa[y][k],k); fa[f2][k]=f1; } int main() { rd(n);rd(m); if(n==1) { printf("0"); re 0; } for(int j=0;(1<<j)<=n;++j) for(int i=1;i<=n-(1<<j)+1;++i) fa[i][j]=i; int l1,l2,r1,r2; inc(i,1,m) { rd(l1),rd(r1),rd(l2),rd(r2); dec(j,20,0) if(l1+(1<<j)-1<=r1) { merge(l1,l2,j); l1+=(1<<j);l2+=(1<<j); } } for(int j=log2(n);j>=1;--j) for(int i=1;i<=n-(1<<j)+1;++i) { int t=find(fa[i][j],j); if(t==i)continue; merge(i,t,j-1); merge(i+(1<<(j-1)),t+(1<<(j-1)),j-1); } long long ans=9,ret=n,a=10; inc(i,1,n) if(find(fa[i][0],0)!=i) --ret; --ret; while(ret) { if(ret&1)ans=(ans*a)%mod; a=(a*a)%mod; ret>>=1; } printf("%lld",ans); re 0; }