luogu P3295 [SCOI2016] Mengmengピリダジン| +互いに素セット乗算

タイトル説明

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;
}

おすすめ

転載: www.cnblogs.com/naruto-mzx/p/12194446.html