Description

一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条
件表示为四个数,l1,r1,l2,r2,即两个长度相同的区间,表示子串Sl1Sl1+1Sl1+2...Sr1与Sl2Sl2+1Sl2+2...S
r2完全相同。比如n=6时,某限制条件l1=1,r1=3,l2=4,r2=6,那么123123,351351均满足条件,但是12012,13
1141不满足条件,前者数的长度不为6,后者第二位与第五位不同。问满足以上所有条件的数有多少个。

Input

第一行两个数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。
 

Output

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

Sample Input

4 2
1 2 3 4
3 3 3 3

Sample Output

90

HINT

Source

陈老师讲的一个题,思路还是很妙的。。。

考虑这个题最后要求的就是有多少种等价类,我们考虑用并查集来实现。。。

如果暴力做的话,给定[l1,r1],[l2,r2],就把这两个区间中对应的位置用并查集并起来。。。

正解的话是ST表的鬼畜应用。。。每个ST[i][j]都代表一个点。。。。

对[l1,r1],[l2,r2],按ST表的那套理论,都拆为两个2^x的区间,然后把对应的区间的点用并查集并起来。。。

然后我们考虑把i从高层往低层下传额外关系,即从2^k -> 2^(k-1),

因为ST[k][j] 可以拆为两个ST[k-1][...]。。。

如果在2^k层,ST[k][i]与ST[k][j]在同一集合,那么在2^(k-1),ST[k-1][i]和ST[k-1][j]在同一集合中,另外一个同理。。。

最后统计,2^0 层有多少个集合就行了。。。

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
typedef long long ll;
const int N=200050;
const int Mod=1e9+7;
int pre[N],pre2[N],ST[20][N],n,m,tt,fa[N*20],tong[N],ans;
struct date{
int x,y;
}g[N*20],la[N*20];
void make_ST(){
pre[0]=1;for(int i=1;i<=18;i++) pre[i]=pre[i-1]<<1;
pre2[0]=-1;for(int i=1;i<=n;i++) pre2[i]=pre2[i>>1]+1;
for(int i=1;i<=n;i++) ST[0][i]=++tt;
for(int i=1;i<=18;i++)
for(int j=1;j<=n;j++){
if(j+pre[i]-1<=n){
ST[i][j]=++tt,g[tt].x=ST[i-1][j],g[tt].y=ST[i-1][j+pre[i-1]];
}
}
for(int i=1;i<=tt;i++) fa[i]=i;
}
int find(int x) {
if(x!=fa[x]) fa[x]=find(fa[x]);
return fa[x];
}
struct data{
int u,v;
};
data query(int l,int r){
int x=pre2[r-l+1];
int u=find(ST[x][l]),v=find(ST[x][r-pre[x]+1]);
return (data){u,v};
}
int main(){
scanf("%d%d",&n,&m);make_ST();
for(int i=1;i<=m;i++){
int l1,r1,l2,r2;scanf("%d%d%d%d",&l1,&r1,&l2,&r2);
data x=query(l1,r1),y=query(l2,r2);
if(x.u!=y.u) fa[x.u]=y.u;
if(x.v!=y.v) fa[x.v]=y.v;
}
for(int i=18;i;i--){
for(int j=1;j<=n;j++){
int x=ST[i][j],y=find(x);
if(!la[y].x){
la[y].x=g[x].x,la[y].y=g[x].y;
}
else{
int u=find(la[y].x),v=find(g[x].x);
if(u!=v) fa[u]=v;
int u1=find(la[y].y),v1=find(g[x].y);
if(u1!=v1) fa[u1]=v1;
la[y].x=g[x].x,la[y].y=g[x].y;
}
}
}
ll ans=1;
for(int i=1;i<=n;i++){
if(!tong[find(ST[0][i])]){
tong[find(ST[0][i])]++;
if(i==1) (ans*=9)%=Mod;
else (ans*=10)%=Mod;
}
}
printf("%lld\n",ans);
return 0;
}

  

bzoj 4569: [Scoi2016]萌萌哒的更多相关文章

  1. BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集

    传送门 BZOJ 4569 题解 ST表和并查集是我认为最优雅(其实是最好写--)的两个数据结构. 然鹅!他俩加一起的这道题,我却--没有做出来-- 咳咳. 正解是这样的: 类似ST表有\(\log ...

  2. BZOJ 4569: [Scoi2016]萌萌哒 [并查集 倍增]

    传送门 题意:长为$n \le 10^5$的数字,给出$m \le 10^5$个限制$[l1,r1]\ [l2,r2]$两个子串完全相等,求方案数 把所有要求相等的位置连起来,不就是$9*10^{连通 ...

  3. bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表

    题目链接 Description 一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每 ...

  4. BZOJ 4569 [Scoi2016]萌萌哒 ——ST表 并查集

    好题. ST表又叫做稀疏表,这里利用了他的性质. 显然每一个条件可以分成n个条件,显然过不了. 然后发现有许多状态是重复的,首先考虑线段树,没什么卵用. 然后ST表,可以每一层表示对应的区间大小的两个 ...

  5. 【BZOJ 4569】 4569: [Scoi2016]萌萌哒 (倍增+并查集)

    4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 865  Solved: 414 Description 一个长 ...

  6. 4569: [Scoi2016]萌萌哒

    4569: [Scoi2016]萌萌哒 链接 分析: 每次给出的两个区间长度是一样的,对应位置的数字也是一样的,那么可以将两两对应的数字用并查集合并,设最后有$cnt$个不同的集合,答案就是$9\ti ...

  7. BZOJ 4569 萌萌哒

    题目传送门 4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MB Submit: 483 Solved: 221 [Submit][S ...

  8. 【LG3295】[SCOI2016]萌萌哒

    [LG3295][SCOI2016]萌萌哒 题面 洛谷 题解 考虑现在我们如果一次只是限定两个位置相等该怎么做, 直接将这些位置用并查集并起来然后答案就是 \[ ans= \begin{cases} ...

  9. 【BZOJ4569】[Scoi2016]萌萌哒 倍增+并查集

    [BZOJ4569][Scoi2016]萌萌哒 Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四 ...

随机推荐

  1. swaggerui在asp.net web api core 中的应用

    Swaggerui 可以为我们的webapi提供美观的在线文档,如下图: 实现步骤: NuGet Packages  Install-Package Swashbuckle.AspNetCore 在s ...

  2. Tinc VPN

    服务端配置 安装 $ apt-get install tinc 配置 $ mkdir -p /etc/tinc/dock/hosts $ cd /etc/tinc/dock 配置 tinc.conf ...

  3. null与undefined的比较

    null在JavaScript中是关键字,它属于一个特殊的值,即空值. 而undefined它不是关键字,它表示未定义,属于预定义的全局变量. null == undefined 返回的是 true  ...

  4. 【微服务】之三:从零开始,轻松搞定SpringCloud微服务-配置中心

    在整个微服务体系中,除了注册中心具有非常重要的意义之外,还有一个注册中心.注册中心作为管理在整个项目群的配置文件及动态参数的重要载体服务.Spring Cloud体系的子项目中,Spring Clou ...

  5. MySQL 性能优化的最佳20多条经验分享(二)(转)

    11. 尽可能的使用 NOT NULL 除非你有一个很特别的原因去使用 NULL 值,你应该总是让你的字段保持 NOT NULL.这看起来好像有点争议,请往下看. 首先,问问你自己"Empt ...

  6. CountDownLatch的实现原理

    CountDownLatch是java并发包中辅助并发的工具类,目的是让并发运行的代码在某一个执行点阻塞,直到所有条件都满足,这里的条件就是调用countDown()方法,有点类似计数器的功能. 用法 ...

  7. LVM挂载失败mount: you must specify the filesystem type

    因意外原因导致机器重启,机器起来后发现磁盘挂载没有了,挂载,结果报错 [root@all /]# mount /dev/hdc2 /mnt/cdrom mount: you must specify ...

  8. java学习笔记IO之File类

    File类总结 p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Times } p.p2 { margin: 0.0px 0.0px 0.0p ...

  9. 遍历输出tuple元素的简洁方式(C++11)

    //遍历输出tuple元素的简洁方式(C++11) //Win32Con17_VS2017_01.cpp #include <iostream> #include <tuple> ...

  10. 移动端 cursor:pointer问题

    之前一直没有注意过,为元素设置上cursor:pointer属性后,会导致元素点击时出现一个蓝色的背景. 为元素设置-webkit-tap-highlight-color: transparent;可 ...