bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表
题目链接
Description
一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每个条件表示为四个数,\(l_1,r_1,l_2,r_2\),即两个长度相同的区间,表示子串\(S_{l1}S_{l1+1}S_{l1+2}...S_{r1}\)与\(S_{l2}S_{l2+1}S_{l2+2}...S_{r2}\)完全相同。
问满足以上所有条件的数有多少个。
思路
参考
https://www.cnblogs.com/owenyu/p/7146428.html
暴力想法
对于每一个条件,将\([l_1,r_1]\)与\([l_2,r_2]\)范围内对应的数一一\(union\)起来,最后检查有多少个集合\(cnt\),答案即为\(10^{cnt-1}*9\).
优化
运用\(ST\)表的思路,但形式与之相反。
一般的\(ST\)表是从小区间中衍伸得到大区间的性质,本题则是从大区间向小区间推。
开\(logn\)个并查集,对于每一个条件,拆成前后两部分分别进行\(union\);
最后从上往下推,将每层的每个大区间拆成下一层的两个小区间。
最后检查最底层。
Code
#include <bits/stdc++.h>
#define F(i, a, b) for (int i = (a); i < (b); ++i)
#define F2(i, a, b) for (int i = (a); i <= (b); ++i)
#define dF(i, a, b) for (int i = (a); i > (b); --i)
#define dF2(i, a, b) for (int i = (a); i >= (b); --i)
#define maxn 100000
#define maxk 17
using namespace std;
typedef long long LL;
bool vis[maxn+10];
int sz[maxk+1][maxn+10], fa[maxk+1][maxn+10], Log[maxn+10], bi[maxk+1], n, m;
inline int find(int dep, int x) {
return fa[dep][x]==x ? x : fa[dep][x]=find(dep, fa[dep][x]);
}
inline void unionn(int dep, int x, int y) {
x = find(dep, x), y = find(dep, y);
if (x==y) return;
if (sz[dep][x]>sz[dep][y]) swap(x, y);
fa[dep][x] = y;
}
void init() {
Log[0] = -1; bi[0] = 1;
F2(i, 1, maxn) Log[i] = Log[i>>1]+1;
int k=Log[n];
F2(i, 1, maxk) {
bi[i] = bi[i-1]<<1;
}
F2(i, 0, maxk) F2(j, 1, n) fa[i][j]=j, sz[i][j]=1;
}
const LL mod=1e9+7;
LL poww(LL a, LL b) {
LL ret=1;
while (b) {
if (b&1) (ret*=a)%=mod;
(a*=a)%=mod;
b>>=1;
}
return ret;
}
int main() {
scanf("%d%d", &n,&m);
init();
F(i, 0, m) {
int l1, r1, l2, r2;
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
int dep=Log[r1-l1+1];
unionn(dep, l1, l2);
unionn(dep, r1-bi[dep]+1, r2-bi[dep]+1);
}
dF(dep, maxk, 0) {
F2(i, 1, n) {
int x=find(dep, i);
unionn(dep-1, i, x);
unionn(dep-1, i+bi[dep-1], x+bi[dep-1]);
}
}
int ans=0;
F2(i, 1, n) ans += (find(0, i)==i);
printf("%lld\n", poww(10, ans-1)*9%mod);
return 0;
}
bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表的更多相关文章
- BZOJ 4569: [Scoi2016]萌萌哒 [并查集 倍增]
传送门 题意:长为$n \le 10^5$的数字,给出$m \le 10^5$个限制$[l1,r1]\ [l2,r2]$两个子串完全相等,求方案数 把所有要求相等的位置连起来,不就是$9*10^{连通 ...
- 洛谷P3295 萌萌哒 并查集 + ST表
又切一道紫题!!! 成功的(看了一吨题解之后),我A掉了第二道紫题. 好,我们仔细观察,发现这是一个排列组合问题. 有些限定条件,要相等的地方,我们就用并查集并起来.最后一查有多少个并查集,就有多少个 ...
- luogu3295 萌萌哒 (并查集+ST表)
如果给相同的位置连边,最后联通块数是n,最后答案就是$9*10^{n-1}$ 但直接连边是$O(n^2)$的 所以事先处理出一个ST表,每次O(1)地给那个ST表连边 最后再一点一点下放,就是把在这层 ...
- [BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增)
[BZOJ4569] [Luogu 3295] [SCOI2016]萌萌哒(并查集+倍增) 题面 有一个n位的十进制数a(无前导0),给出m条限制,每条限制\((l_1,r_1,l_2,r_2)(保证 ...
- BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集
传送门 BZOJ 4569 题解 ST表和并查集是我认为最优雅(其实是最好写--)的两个数据结构. 然鹅!他俩加一起的这道题,我却--没有做出来-- 咳咳. 正解是这样的: 类似ST表有\(\log ...
- BZOJ 4569 [Scoi2016]萌萌哒 ——ST表 并查集
好题. ST表又叫做稀疏表,这里利用了他的性质. 显然每一个条件可以分成n个条件,显然过不了. 然后发现有许多状态是重复的,首先考虑线段树,没什么卵用. 然后ST表,可以每一层表示对应的区间大小的两个 ...
- LOJ2014 SCOI2016 萌萌哒 并查集、ST表优化连边
传送门 一个朴素的做法就是暴力连边并查集,可是这是\(O(n^2)\)的.发现每一次连边可以看成两个区间覆盖,这两个区间之间一一对应地连边.可线段树对应的两个节点的size可能不同,这会导致" ...
- Luogu P3295 [SCOI2016]萌萌哒(并查集+倍增)
P3295 [SCOI2016]萌萌哒 题面 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \cdots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位, ...
- bzoj 4569: [Scoi2016]萌萌哒
Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两个长度相同的 ...
随机推荐
- es6中类的注意事项
class Circle { constructor(radius) { this.radius = radius; Circle.circlesMade++; }; static draw(circ ...
- nginx启动和配置
1.命令行参数 -c </path/to/config> 为 Nginx 指定一个配置文件,来代替缺省的.路径应为绝对路径 -t 不运行,而仅仅测试配置文件.nginx 将检查配置文件的语 ...
- 【转】ASP.NET Core 快速入门(环境篇)
原文链接:http://www.cnblogs.com/zhaopei/p/netcore.html [申明]:本人.NET Core小白.Linux小白.MySql小白.nginx小白.而今天要说是 ...
- LCA(最近公共祖先)——LCA倍增法
一.前人种树 博客:最近公共祖先 LCA 倍增法 博客:浅谈倍增法求LCA 二.沙场练兵 题目:POJ 1330 Nearest Common Ancestors 代码: const int MAXN ...
- lubuntu 使用USB摄像头
http://liangbing8612.blog.51cto.com/2633208/598762 Most of the camera driver has integrated in the k ...
- js保留两位小数,不四舍五入
//不进行四舍五入,保留两位小数 function getKeepTwoDecimals(val) { var newVal = (parseInt(val * 100) / 100).toFixed ...
- 团队作业4——第一次项目冲刺(Alpha版本)-第二篇
项目冲刺——第二阶段 度过了敏捷冲刺,各个成员积极汇报各自的工作.好了,着手下一步规划! Mission 团队成员 任务 郭达 实现PHP后台的答题判分查看正确率 刘德培 编写博客 石浩洋 实现 ...
- Jekyll 使用入门
Jekyll 是一个网站生成工具,可以用来将带有一定格式的文本(如:MarkDown)转换成静态的HTML页面, 并提供了Liquid模板引擎进行页面渲染,然后可以将生成的静态网站发布到如 Githu ...
- 安装和配置hadoop集群步骤
hadoop集群的安装步骤和配置 hadoop是由java语言编写的,首先我们肯定要在电脑中安装jdk,配置好jdk的环境,接下来就是安装hadoop集群的步骤了,在安装之前需要创建hadoop用户组 ...
- ns统计使用资源的SNMP OID
ns统计使用资源的SNMP OID > add snmp manager 192.168.195.1 > add snmp community public ALL > add sn ...