题目链接

BZOJ4569

题解

倍增的思想很棒

题目实际上就是每次让我们合并两个区间对应位置的数,最后的答案\(ans = 9 \times 10^{tot - 1}\),\(tot\)是联通块数,因为要去前导\(0\),首位不为\(0\)即可

如何快速合并两个区间?

倍增!

每次合并两个区间,我们就利用倍增分成\(logn\)个区间,先用并查集维护其联通性

合并完之后,由大区间推向小区间,将每个倍增的大区间分成两半,分别和其联通块的代表区间的两半合并

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
using namespace std;
const int maxn = 100005,maxm = 100005,INF = 1000000000,P = 1000000007;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int n,m,cnt,pre[maxn * 20],sta[maxn * 20],f[maxn][20],bin[30];
int qpow(int a,int b){
int ans = 1;
for (; b; b >>= 1,a = 1ll * a * a % P)
if (b & 1) ans = 1ll * ans * a % P;
return ans;
}
inline int find(int u){return u == pre[u] ? u : pre[u] = find(pre[u]);}
inline void merge(int a,int b){
int fa = find(a),fb = find(b);
pre[max(fa,fb)] = min(fa,fb);
}
int main(){
bin[0] = 1; for (int i = 1; i <= 25; i++) bin[i] = bin[i - 1] << 1;
n = read(); m = read();
for (int j = 0; j <= 17; j++)
for (int i = 1; i <= n; i++){
if (i + bin[j] - 1 > n) break;
f[i][j] = ++cnt; sta[cnt] = i; pre[cnt] = cnt;
}
int l,r,ll,rr,len;
while (m--){
l = read(); r = read(); ll = read(); rr = read();
len = r - l + 1;
for (int i = 17; i >= 0; i--)
if (l + bin[i] - 1 <= r){
merge(f[l][i],f[ll][i]);
l += bin[i]; ll += bin[i];
}
}
int u;
for (int j = 17; j; j--)
for (int i = 1; i <= n; i++){
if (i + bin[j] - 1 > n) break;
u = find(f[i][j]);
if (sta[u] != i){
merge(f[i][j - 1],f[sta[u]][j - 1]);
merge(f[i + bin[j - 1]][j - 1],f[sta[u] + bin[j - 1]][j - 1]);
}
}
int tot = 0;
for (int i = 1; i <= n; i++) if (find(f[i][0]) == f[i][0]) tot++;
printf("%lld\n",9ll * qpow(10,tot - 1) % P);
return 0;
}

BZOJ4569 [SCOI2016]萌萌哒 【并查集 + 倍增】的更多相关文章

  1. [bzoj4569][SCOI2016]萌萌哒-并查集+倍增

    Brief Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两 ...

  2. [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增)

    [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增) 题面 有一个n位的十进制数a(无前导0),给出m条限制,每条限制\((l_1,r_1,l_2,r_2)(保证 ...

  3. Luogu P3295 [SCOI2016]萌萌哒(并查集+倍增)

    P3295 [SCOI2016]萌萌哒 题面 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \cdots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位, ...

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

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

  5. 洛谷 3295 [SCOI2016]萌萌哒——并查集优化连边

    题目:https://www.luogu.org/problemnew/show/P3295 当要连的边形如 “一段区间内都是 i 向 i+L 连边” 的时候,用并查集优化连边. 在连边的时候,如果要 ...

  6. LOJ2014 SCOI2016 萌萌哒 并查集、ST表优化连边

    传送门 一个朴素的做法就是暴力连边并查集,可是这是\(O(n^2)\)的.发现每一次连边可以看成两个区间覆盖,这两个区间之间一一对应地连边.可线段树对应的两个节点的size可能不同,这会导致" ...

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

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

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

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

  9. 2018.07.31 bzoj4569: [Scoi2016]萌萌哒(并查集+倍增)

    传送门 对于每个限制,使用倍增的二进制拆分思想,用并查集数组fa[i][j]" role="presentation" style="position: rel ...

随机推荐

  1. python中使用空格还是使用 Tab键缩进的建议

    对于程序员来说,其实Tab和空格远远不只是“立场”问题那么简单. 在不同的编辑器里tab的长度可能不一致,所以在一个编辑器里用tab设置缩进后,在其它编辑器里看可能缩进就乱了.空格不会出现这个问题,因 ...

  2. JavaScript 转载

    JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...

  3. python装饰器+递归+冒泡排序

    冒泡排序 li = [33, 2, 10, 1,23,23523,5123,4123,1,2,0] for k in range(1,len(li)): for i in range(len(li) ...

  4. ruby 数据类型Number

    Ruby支持的数据类型包括基本的Number.String.Ranges.Symbols,以及true.false和nil这几个特殊值,同时还有两种重要的数据结构——Array和Hash 数值类型(N ...

  5. Java——Random类随机整数---18.10.11

    一.Random类的定义 1.Random类位于java.util包中,主要用于生成 伪随机数 2.random类将 种子数 作为随机算法的起源数字,计算生成伪随机数,其与生成的随机数字的区间无关 3 ...

  6. Oozie Coordinator job 之定时任务

    使用 Coordinator job 可以执行定时任务和时间触发执行 需要注意的是 Oozie 默认使用的时区与中国时区不是一致的,需要进行一点修改 1.关于时区 a.修改 core-site.xml ...

  7. 第5模块闯关Bootstrap

    “行(row)”必须包含在 .container (固定宽度)或 .container-fluid (100% 宽度)中,以便为其赋予合适的排列(aligment)和内补(padding). 通过“行 ...

  8. 10-mongodb启动错误

    1.error信息 python@ubuntu:~$ mongod --22T17:: I CONTROL [initandlisten] MongoDB starting : pid= port= ...

  9. cmd中可以运行java,但不能运行javac命令

    在cmd中可以运行java,但运行javac命令时提示:'javac' 不是内部或外部命令,也不是可运行的程序或批处理文件. 原因:安装java时把jdk的路径和jre的路径选择成一样,就造成覆盖了. ...

  10. LINUX系统配置相关

    修改系统引导文件 grub.cfg的文件位置   /boot/grub/grub.cfg set default="4"  默认windows是在第四个选项 set timeout ...