【洛谷3295】[SCOI2016]萌萌哒
倍增并查集。
//Twenty #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<cmath> #include<ctime> #include<queue> using namespace std; typedef long long LL; const int maxn=1e5+5; const int mod=1e9+7; int f[maxn][20],n,m; void read(int &ret) { int f=1; ret=0; char ch=getchar(); while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar(); if(ch=='-') f=-1,ch=getchar(); for(;ch>='0'&&ch<='9';ch=getchar()) ret=ret*10+ch-'0'; ret*=f; } int find(int x,int l) { return x==f[x][l]?x:f[x][l]=find(f[x][l],l); } void link(int u,int v,int l) { if(find(u,l)==find(v,l)) return; f[f[u][l]][l]=f[v][l]; } void init() { read(n); read(m); for(int i=1;i<=n;i++) for(int j=0;j<20;j++) f[i][j]=i; for(int i=1;i<=m;i++) { int a,b,c,d; read(a); read(b); read(c); read(d); for(int j=19;j>=0;j--) { if(a+(1<<j)-1<=b) { link(a,c,j); a+=(1<<j); c+=(1<<j); } } } for(int j=19;j>=1;j--) { for(int i=1;(i+(1<<j)-1)<=n;i++) { link(i,find(i,j),j-1); link(i+(1<<j-1),f[i][j]+(1<<j-1),j-1); } } int cnt=0; LL ans=9; for(int i=1;i<=n;i++) if(find(i,0)==i) cnt++; for(int i=1;i<cnt;i++) { (ans*=10)%=mod; } printf("%lld\n",ans); } int main() { init(); return 0; }