タイトル説明
SiS_iSi IIIはビットを表すS1S2S3⋯SnS_1S_2S_3 \ cdots S_nS1 S2 S3⋯SNを有する多数の長さ、とのnnnは、S1S_1S1は最大数です。あなたにいくつかの制限を教えて、各状態は4つの数字、L1として表され、R1、L2、r2l_1、R_1、L_2、r_2l1、R1、L2、R2、すなわち、同じ長さの2つのセクション、サブストリングSl1Sl1 + 1Sl1 + 2⋯Sr1S_ {L_1} S_ {L_1 + 1} S_ {L_1 + 2} \ cdots S_ {R_1} SL1 SL1 +1 SL1 +2⋯Sr1をとSl2Sl2 + 1Sl2 + 2⋯Sr2S_ {L_2} S_ {L_2 + 1} S_ {L_2 + 2} \ cdots S_ {R_2} SL2 SL2 +1 SL2 +2⋯SR2が同じ。
例えばときN 6N 6N = 6 = =、制限L1 = 1、R 1 = 3、L2 = 4、R 2 = 6l_1 = 1、R_1 = 3、L_2 = 4、R_2 = 6L1 = 1、R1 = 3 、L2 = 4、R = 6、次いで123123123123123123,351351351351351351条件を満足するが、120121201212012,131141131141131141条件が満たされていない、元の長さは、第二及び第五の異なる番号666ではありません。以上のいくつかは、どのように多く満たすすべての条件を求めました。
入力形式
最初の2つの行nおよびmは、それぞれ多数の長さ、及び制約の数を表します。
次のm行目、第i行、数4 LI1、RI1、LI2、RI2のために、2つのセクションでは、それぞれの制約に対応します。
1≤n≤1051\ n \ 1051≤n≤105,1≤m≤1051^ \ M \ 10 ^51≤m≤105、1≤li1、RI1、LI2、ri2≤n1 \ LI1、RI1、LI2、RI2 \ N1≤li1、RI1、LI2、ri2≤n;并且保证RI1、RI2 = LI1、LI2 RI1、RI2 = LI1、LI2 RI1、RI2 = LI1、LI2。
出力フォーマット
満たされたすべての条件の長さ及びn多数の数を表す数は、答えが大きくなることが、出力結果109応答モード109から10 ^ 9 + 7 + 7 + 7。
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int _=1e5+10,N=16,p=1e9+7,mod=1e9+7;
#define int long long
int n,m,f[22][_];
int get(int x,int y){
return f[y][x]==x?x:f[y][x]=get(f[y][x],y);
}
bool vis[_];
inline int ksm(int x,int y){
int res=1;
while(y){
if(y&1)res=res*x%mod;
x=x*x%mod; y>>=1;
}
return res;
}
void merge(int x,int y,int len){
if(get(x,len)!=get(y,len))
f[len][f[len][x]]=f[len][y];
}
signed main(){
cin>>n>>m;
for(int j=0;j<=21;j++)for(int i=1;i<=n;i++)f[j][i]=i;
int l1,l2,r1,r2;
for(int i=1;i<=m;i++){
scanf("%lld%lld%lld%lld",&l1,&r1,&l2,&r2);
for(int j=20;j>=0;j--)
if(l1+(1<<j)-1<=r1)merge(l1,l2,j),l1+=1<<j,l2+=1<<j;
}
int ans=9,cnt=0;
for(int j=20;j;j--)
for(int i=1;i+(1<<j)-1<=n;i++)
{merge(i,get(i,j),j-1);merge(i+(1<<(j-1)),f[j][i]+(1<<(j-1)),j-1);}
for(int i=1;i<=n;i++)if(get(i,0)==i)cnt++;
for(int i=1;i<cnt;i++)ans*=10,ans%=mod;
cout<<ans<<endl;
}