[SCOI2016] Mengmeng

Topic description

A large number of length n is represented by S1S2S3...Sn, where Si represents the i-th bit of the number, S1 is the highest bit of the number, and tells you some restrictions, each condition is represented as four numbers, l1, r1 , l2, r2, that is, two intervals with the same length, indicating that the substrings Sl1Sl1+1Sl1+2...Sr1 are exactly the same as Sl2Sl2+1Sl2+2...Sr2.

For example, when n=6, a certain restriction condition l1=1, r1=3, l2=4, r2=6, then 123123, 351351 satisfy the condition, but 12012, 131141 do not satisfy the condition, the length of the former number is not 6, the latter The second is different from the fifth. Ask how many numbers meet all of the above conditions.

Input and output format

Input format:

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

Next m lines, for the i-th line, there are 4 numbers li1, ri1, li2, ri2, which respectively represent the two intervals corresponding to the restriction condition. 1<=n<=10^5, 1<=m<=10^5, 1<=li1,ri1,li2,ri2<=n; and ri1-li1=ri2-li2 is guaranteed.

Output format:

A number that represents the number of large numbers of length n that satisfy all conditions. The answer may be very large, so output the result of the answer modulo 10^9+7.

Input and output example

Input Example #1: Copy
4 2
1 2 3 4
3 3 3 3
Output Sample #1: Copy
90 
Use the union search set to maintain the connectivity relationship
Let logn union search set
i-th union search set j point and k point are connected to express [j~j+2^i]=[k~k+2^i]
, then you can From the back to the front, pass the information of the i-th union to the i-1th.
Let the 0th union-check set have cnt connected blocks
, then the answer is $9*10^{cnt-1}$
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int set[25][100011],ans,Mod=1e9+7,n,m,Log[100011],cnt;
 8 int find(int t,int x)
 9 {
10   if (set[t][x]!=x) set[t][x]=find(t,set[t][x]);
11   return set[t][x];
12 }
13 void merge(int t,int x,int y)
14 {
15   int p=find(t,x);
16   int q=find(t,y);
17   if (p!=q)
18     {
19       set[t][p]=q;
20     }
21 }
22 int main()
23 {int i,j,l1,l2,r1,r2,len;
24   cin>>n>>m;
25   for (i=2;i<=n;i++)
26     {
27       Log[i]=Log[i/2]+1;
28     }
29   for (i=0;i<=Log[n];i++)
30     for (j=1;j<=n;j++)
31       set[i][j]=j;
32   for (i=1;i<=m;i++)
33     {
34       scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
35       len=Log[r1-l1+1];
36       merge(len,l1,l2);
37       merge(len,r1-(1<<len)+1,r2-(1<<len)+1);
38     }
39   for (i=Log[n];i>=1;i--)
40     {
41       for (j=1;j+(1<<i)-1<=n;j++)
42     {
43       int k=find(i,j);
44       if (j==k) continue;
45       merge(i-1,j,k);
46       merge(i-1,j+(1<<i-1),k+(1<<i-1));
47     }
48     }
49   ans=9;
50   for (i=1;i<=n;i++)
51     if (find(0,i)==i) cnt++;
52   for (i=1;i<cnt;i++)
53     ans=1ll*10*ans%Mod;
54   cout<<ans;
55 }

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325096290&siteId=291194637