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. 深入了解Android蓝牙Bluetooth——《基础篇》

    什么是蓝牙?   也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的.利用"蓝牙"技术,能够有效地简化掌上电脑.笔记本电 ...

  2. Android 软键盘的显示和隐藏,这样操作就对了

    一.前言 如果有需要用到输入的地方,通常会有需要自动弹出或者收起软键盘的需求.开篇明义,本文会讲讲弹出和收起软键盘的一些细节,最终还会从源码进行分析. 想要操作软键盘,需要使用到 InputMetho ...

  3. Linux服务器制定mysql数据库备份的计划任务

    首先,创建一个shell脚本: Shell #!/bin/bash mysql_pwd="1234567890" mysql_dump="/usr/local/mysql ...

  4. php结合redis实现高并发下的抢购、秒杀功能 (转载)

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个: 1 高并发对数据库产生的压力 2 竞争状态下如何解决库存的正确减少("超卖"问题) 对于第一个问题,已经很容易想到 ...

  5. phpcms的验证码替换 及 phpcms实现全站搜索功能

    在使用phpcms替换网页的时候,除了正常的替换栏目.内容页等,其他的什么验证码啦,提交表单了,搜索功能了,这些在替换的时候可能会对一些默认文件有一些小小 的改变 下面就是自己在失败中成功的过程,最后 ...

  6. S2b只适合于电商吗?

    万物互联时代,任何产业蓬勃发展都离不开互联网,从B2M.B2B.B2C.C2C.M2M,层出不穷的商业模式都让人眼花缭乱,最近还推出了s2b这个全新的模式. S代表着大的供应平台,它将更好地赋能给更多 ...

  7. 1267 - Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '=' | 1267 - Illegal mix of collations (gbk_chinese_ci,IMPLICIT) and (Latin,COERCIBL)

    select * FROM information_schema.columns WHERE table_schema = "databaseName" and collation ...

  8. SQL-Oracle游标

    游标提供了一种从集合性质的结果集中提供出单条记录的手段.初始时指向首记录. 游标的种类 静态游标.REF游标 静态游标:能够理解为一个数据快照,打开游标后的结果集是数据库表中数据的备份,数据不会对表的 ...

  9. Oracle中用户(User)和模式(Schema)的概念

    数据库理论中数据库用户和数据库模式并没有必定的联系.具体的数据库模式解释能够在这里找到: http://stackoverflow.com/questions/2674222/what-is-purp ...

  10. 【ODPS】TableTunnel单线程简单下载事例

    ODPS Tunnel是ODPS的数据通道,用户能够通过Tunnel向ODPS中上传或者下载数据.眼下Tunnel仅支持表(不包含视图View)数据的上传下载. 主要接口 描写叙述 TableTunn ...