4569: [Scoi2016]萌萌哒

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 459  Solved: 209
[Submit][Status][Discuss]

Description

一个长度为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,后者第二位与第五位不同。问满足以上所有条件的数有多少个。

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

Solution

这道题非常巧妙

先思考暴力,对每一位维护一个并查集,每次限制就是把那两个区间信息合并,最后答案根据剩有的计算即可

那么问题在于如何快速的合并

考虑线段树,分出来的区间过多,合并还是有问题,所以换种方法

倍增!建立ST表,相当于对同层的建出一棵类似树的东西,每层维护并查集,相当于把信息拆成$2^{?}$的两段

合并优先合并大的,这样一共是$nlogn$段,最多合并$nlogn$次

递归合并,发现合并过就可以跳出了,总的答案统计一下用快速幂计算一下即可

特判N=1

总的时间复杂度$O(nlogn*a(n))$

启发:倍增并不仅仅应用于LCA或SA求LCP之类的,应该灵活运用这种思想

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
void Freopen() {freopen("game.in","r",stdin); freopen("game.out","w",stdout);}
#define P 1000000007
inline int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
int N,M;
long long Quick_Pow(long long x,long long y)
{
long long re=;
for (int i=y; i; i>>=,x=x*x%P)
if (i&) re=re*x%P;
return re;
}
#define MAXN 100010
int fa[MAXN][];
int Find(int x,int y) {if (fa[x][y]==x) return x; else return fa[x][y]=Find(fa[x][y],y);}
void Merge(int x1,int x2,int k)
{
int f1=Find(x1,k),f2=Find(x2,k);
if (f1==f2) return;
fa[f1][k]=f2;
if (k--) {Merge(x1,x2,k),Merge(x1+(<<k),x2+(<<k),k);}
}
int Len;
int main()
{
Freopen();
N=read(),M=read();
for (int i=; i<=N; i++)
for (int j=; j<=; j++)
fa[i][j]=i;
while (M--)
{
int l1=read(),r1=read(),l2=read(),r2=read();
int k=; while ((<<k)<=r1-l1+) k++; k--;
Merge(l1,l2,k); Merge(r1-(<<k)+,r2-(<<k)+,k);
}
for (int i=; i<=N; i++) if (fa[i][]==i) Len++;
printf("%d\n",N==? :int(9LL*Quick_Pow(,Len-)%P));
return ;
}

【BZOJ-4569】萌萌哒 ST表 + 并查集的更多相关文章

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

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

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

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

  3. bzoj4569: [Scoi2016]萌萌哒(ST表+并查集)

    好喵喵的题 将一个要求用ST表分割成logn个要求,如果把f[i][j]和f[u][v]在同一个集合,那么f[i][j-1]和f[u][v-1],f[i+2^(j-1)][j-1]和f[u][u+2^ ...

  4. SQL Server利用RowNumber()内置函数与Over关键字实现通用分页存储过程(支持单表或多表结查集分页)

    SQL Server利用RowNumber()内置函数与Over关键字实现通用分页存储过程,支持单表或多表结查集分页,存储过程如下: /******************/ --Author:梦在旅 ...

  5. BZOJ.2054.疯狂的馒头(并查集)

    BZOJ 倒序处理,就是并查集傻题了.. 并查集就是确定下一个未染色位置的,直接跳到那个位置染.然而我越想越麻烦=-= 以为有线性的做法,发现还是要并查集.. 数据随机线段树也能过去. //18400 ...

  6. 2021.08.03 BZOJ 疯狂的馒头(并查集)

    2021.08.03 BZOJ 疯狂的馒头(并查集) 疯狂的馒头 - 题目 - 黑暗爆炸OJ (darkbzoj.tk) 重点: 1.并查集的神奇运用 2.离线化 题意: 给一个长为n的序列,进行m次 ...

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

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

  8. BZOJ 4569 萌萌哒

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

  9. BZOJ4569 SCOI2016萌萌哒(倍增+并查集)

    一个显然的暴力是用并查集记录哪些位之间是相等的.但是这样需要连nm条边,而实际上至多只有n条边是有用的,冗余过多. 于是考虑优化.使用类似st表的东西,f[i][j]表示i~i+2^j-1与f[i][ ...

随机推荐

  1. ext 自带搜索功能

  2. 转:openwrt中luci学习笔记

    原文地址:openwrt中luci学习笔记 最近在学习OpenWrt,需要在OpenWrt的WEB界面增加内容,本文将讲述修改OpenWrt的过程和其中遇到的问题. 一.WEB界面开发         ...

  3. oracle 取前10条记录

    1.oracle 取前10条记录 1) select * from tbname where rownum < 11; 2) select * from (select * from tbnam ...

  4. ubuntu14.04禁用guest用户登录

    打开终端(ctrl+alt+t) sudo  echo -e "[SeatDefaults]\nallow-guest=false"  > /usr/share/lightd ...

  5. 汤姆大叔的6道javascript编程题题解

    看汤姆大叔的博文,其中有篇(猛戳这里)的最后有6道编程题,于是我也试试,大家都可以先试试. 1.找出数字数组中最大的元素(使用Math.max函数) var a = [1, 2, 3, 6, 5, 4 ...

  6. 《深入理解Spark:核心思想与源码分析》(前言及第1章)

    自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...

  7. 2015/11/9用Python写游戏,pygame入门(8):按钮和游戏结束

    昨天没有更新内容,今天相对多写一些. 因为我们已经基本完成游戏框架,但是游戏结束后,并不知道怎样比较好开始.我本来本着懒的原则,想结束后显示一个黑屏,然后你重新点一下鼠标就重新开始.但是那样实在太不像 ...

  8. ArcEngine选中面要素样式修改

    //只用前五行,可以直接将选中的面要素的颜色全部修改成红色,也就是填充颜色 IRgbColor pRgbColor= new RgbColor();; pRgbColor.Red = ; pRgbCo ...

  9. Bootstrap系列 -- 2. 标题

    一. Bootstrap标题 在Bootstrap中使用标题和Html本身没有太大的区别使用h1-h6, 而Bootstrap只是默认修改了H1-h6的样式,网上找到如下资料参考 二. Bootstr ...

  10. HFS汉化版|简易HTTP服务器

    专为个人用户所设计的 HTTP 档案系统 - Http File Server,如果您觉得架设 FTP Server 太麻烦,那么这个软件可以提供您更方便的档案传输系统,下载后无须安装,只要解压缩后执 ...