luogu P3295 [SCOI2016] pyridazin Mengmeng | + disjoint-set multiplication

Title Description

Nnn with a length of large numbers, with S1S2S3 ⋯ SnS_1S_2S_3 \ cdots S_nS1 S2 S3 ⋯ Sn, where SiS_iSi iii represents the bit, S1S_1S1 is the highest number. Tell you some restrictions, each condition is represented as four numbers, l1, r1, l2, r2l_1, r_1, l_2, r_2l1, r1, l2, r2, i.e., two sections of the same length, a substring Sl1Sl1 + 1Sl1 + 2 ⋯ Sr1S_ {l_1} S_ {l_1 + 1} S_ {l_1 + 2} \ cdots S_ {r_1} Sl1 Sl1 +1 Sl1 +2 ⋯ Sr1 and Sl2Sl2 + 1Sl2 + 2 ⋯ Sr2S_ {l_2} S_ {l_2 + 1} S_ {l_2 + 2} \ cdots S_ {r_2} Sl2 Sl2 +1 Sl2 +2 ⋯ Sr2 identical.

For example when n 6n 6n = 6 = =, a restriction l1 = 1, r1 = 3, l2 = 4, r2 = 6l_1 = 1, r_1 = 3, l_2 = 4, r_2 = 6l1 = 1, r1 = 3 , l2 = 4, r2 = 6, then 123123123123123123,351351351351351351 satisfy the condition, but 120121201212012,131141131141131141 condition is not satisfied, the length of the former is not the number 666, which is different from the second and fifth. More than a few asked how many meet all the conditions.

Input Format

The first two row n and m, respectively represent the length of the large numbers, and the number of constraints.

Next m-th row, for i-th row, the number 4 li1, ri1, li2, ri2, two sections respectively corresponding to the constraint.

1≤n≤1051 \ n \ 10 51≤n≤105,1≤m≤1051 ^ \ m \ 10 ^ 51≤m≤105, 1≤li1, ri1, li2, ri2≤n 1 \ the li1, ri1, li2, ri2 \ n 1≤li1, ri1, li2, ri2≤n; 并且 保证 ri1-li1 = ri2-li2 ri1-li1 = ri2-li2 ri1-li1 = ri2-li2.

Output Format

A number representing the length of all conditions are met and the number of large numbers n, the answer may be large, the output result 109 answer mode 10 ^ 9 + 7 + 7 + 7 to 109.


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

Guess you like

Origin www.cnblogs.com/naruto-mzx/p/12194446.html