help(0pts)
查看原帖
help(0pts)
1083200
guojiahong楼主2024/7/5 16:02
#include<bits/stdc++.h>
using namespace std;
int fa[100001][18],siz[100001][18];
int find(int h,int c)
{
	if(fa[h][c]=h)return h;
	else return fa[h][c]=find(fa[fa[h][c]][c],c);
}
long long _10(int a)//计算10的a次方 
{
	long long ans=1,t=10;
	while(a)
	{
		if(a%2==1)
		{
			ans*=t;
			a--;
			ans%=1000000007;
		}
		else
		{
			t*=t;
			a/=2;
			t%=1000000007;
		}
	}
	return ans;
}
int main(){
	int n,m;
	cin>>n>>m;
	int _=__lg(n);//求log n 
	for(int i=0;i<=_;i++)//初始化 
	{
		for(int j=1;j+(1<<i)-1<=n;j++)
		{
			fa[j][i]=j;
			siz[j][i]=1;
		}
	}
	int l1,r1,l2,r2;
	for(int i=1;i<=m;i++)
	{
		cin>>l1>>r1>>l2>>r2;
		int t=0;
		while(r1-l1-t) //当l1不等于r1时(二进制拆分),进入循环 
		{
			for(int i=0;i<=18;i++)//倍增 
			{
				if(r1-l1-t<(1<<i))
				{
					if(siz[find(l1+t,i-1)][i-1]<siz[find(l2+t,i-1)][i-1])//启发式合并 
					{
						siz[find(l2+t,i-1)][i-1]+=siz[find(l1+t,i-1)][i-1];
						fa[find(l2+t,i-1)][i-1]=find(l1+t,i-1);
					}
					else
					{
						siz[find(l1+t,i-1)][i-1]+=siz[find(l2+t,i-1)][i-1];
						fa[find(l1+t,i-1)][i-1]=find(l2+t,i-1);
					} 
					t+=(1<<(i-1));
					break;
				}
			}
		}
	}
	for(int i=_;i>0;i--)//下传答案 
	{
		for(int j=1;j+(1<<i)-1<=n;j++)
		{
			fa[find(j,i-1)][i-1]=fa[j][i];
			fa[find(j+(1<<(i-1))-1,i-1)][i-1]=fa[j][i]+(1<<(i-1))-1;
		}
	}
	long long ans=0; 
	for(int i=1;i<=n;i++)if(fa[i][0]==i)ans++;//算出有几个集合 
	ans=9*_10(ans-1)%1000000007;//方案数 
	cout<<ans;
	return 0;
}
2024/7/5 16:02
加载中...