zoukankan      html  css  js  c++  java
  • [SCOI2016]萌萌哒

    题目描述

    一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1+1Sl1+2...Sr1与Sl2Sl2+1Sl2+2...Sr2完全相同。

    比如n=6时,某限制条件l1=1,r1=3,l2=4,r2=6,那么123123,351351均满足条件,但是12012,131141不满足条件,前者数的长度不为6,后者第二位与第五位不同。问满足以上所有条件的数有多少个。

    输入输出格式

    输入格式:

    第一行两个数n和m,分别表示大数的长度,以及限制条件的个数。

    接下来m行,对于第i行,有4个数li1,ri1,li2,ri2,分别表示该限制条件对应的两个区间。1<=n<=10^5,1<=m<=10^5,1<=li1,ri1,li2,ri2<=n;并且保证ri1-li1=ri2-li2。

    输出格式:

    一个数,表示满足所有条件且长度为n的大数的个数,答案可能很大,因此输出答案模10^9+7的结果即可。

    输入输出样例

    输入样例#1: 复制
    4 2
    1 2 3 4
    3 3 3 3
    输出样例#1: 复制
    90
    用并查集维护连通关系
    设logn个并查集
    第i个并查集的j点与k点连通表示[j~j+2^i]=[k~k+2^i]
    于是就可以从后往前,把第i个并查集的信息传到第i-1个
    设第0个并查集有cnt个连通块
    那么答案就是$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 }
  • 相关阅读:
    流光shader 和 流光+扭曲shader
    unity3d android动态更新dll
    Shader之溶解效果的几种实现方法
    我的第一个法线贴图
    windows 函数
    MFC 消息框
    C++ MFC棋牌类小游戏day1
    C++STL 预定义函数对象和函数适配器
    C++STL 函数对象和谓词
    C++STL 算法
  • 原文地址:https://www.cnblogs.com/Y-E-T-I/p/8969786.html
Copyright © 2011-2022 走看看