LOJ2014 SCOI2016 萌萌哒 并查集、ST表优化连边
一个朴素的做法就是暴力连边并查集,可是这是\(O(n^2)\)的。发现每一次连边可以看成两个区间覆盖,这两个区间之间一一对应地连边。可线段树对应的两个节点的size可能不同,这会导致“一一对应”的条件在线段树上失效。所以我们需要使用ST表来完成连边。
对原序列建好ST表,对于每一个修改将两个区间覆盖到ST表上然后两两之间连边。注意在ST表上连边的两个区间要对应,即如果ST表上对应\([l,r]\)的区间与对应\([L,R]\)的区间连了边,意味着对于\(\forall i \in [0 , r - l],\)有边\((l + i , L + i)\)。
这样连边的复杂度是\(O(nlogn)\)的,但是查询就比较麻烦了,因为我们并查集只能查询大小为\(1\)的区间,而不能混入这些奇奇怪怪的区间。
但是我们可以把每一层ST表对应的并查集向下传,直到传到最底层。具体来说从上往下遍历每一层ST表对应的并查集,找到第\(i\)个点和它在这一层并查集上的根。这两个点在下一层的ST表中分别对应两个点,而连边的时候又是对应的,所以将它们的左儿子之间连边、右儿子之间连边即可。
总复杂度\(O(nlogn)\)
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
//This code is written by Itst
using namespace std;
inline int read(){
int a = 0;
char c = getchar();
while(!isdigit(c))
c = getchar();
while(isdigit(c)){
a = a * 10 + c - 48;
c = getchar();
}
return a;
}
const int MAXN = 100007 , MOD = 1e9 + 7;
int ST[19][MAXN];
int N , M , cnt , logN , head[MAXN << 3] , dir[MAXN * 20] , fa[MAXN * 20];
void init(){
for(logN = 0 ; 1 << logN <= N ; ++logN)
for(int j = 1 ; j + (1 << logN) - 1 <= N ; ++j){
ST[logN][j] = ++cnt;
dir[cnt] = j;
fa[cnt] = cnt;
}
--logN;
}
int find(int a){return fa[a] == a ? a : (fa[a] = find(fa[a]));}
void merge(int a , int b){fa[find(a)] = find(b);}
inline void add(int a , int b , int len){
for(int i = 18 ; i >= 0 ; --i)
if(len & (1 << i)){
merge(ST[i][a] , ST[i][b]);
a += 1 << i;
b += 1 << i;
}
}
int main(){
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
//freopen("out","w",stdout);
#endif
N = read(); M = read();
init();
for(int i = 1 ; i <= M ; ++i){
int a = read() , b = read() , c = read();
read();
add(a , c , b - a + 1);
}
for(int i = logN ; i ; --i)
for(int j = 1 ; j + (1 << i) - 1 <= N ; ++j){
int t = find(ST[i][j]);
if(t != ST[i][j]){
int x = dir[t];
merge(ST[i - 1][j] , ST[i - 1][x]);
merge(ST[i - 1][j + (1 << i - 1)] , ST[i - 1][x + (1 << i - 1)]);
}
}
bool f = 0;
int ans = 1;
for(int i = 1 ; i <= N ; ++i)
if(fa[i] == i){
ans = ans * (9ll + f) % MOD;
f = 1;
}
cout << ans;
return 0;
}
LOJ2014 SCOI2016 萌萌哒 并查集、ST表优化连边的更多相关文章
- bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表
题目链接 Description 一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每 ...
- 洛谷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)(保证 ...
- 2018.09.25 codeforces1053E. Euler tour(并查集+st表+模拟)
传送门 毒瘤细节题. 首先考虑不合法的情况. 先把相同的值配对,这样就构成了一些区间. 那么如果这些区间有相交的话,就不合法了. 如何判断?DZYO安利了一波st表,我觉得很不错. 接着考虑两个相同的 ...
- Luogu P3295 [SCOI2016]萌萌哒(并查集+倍增)
P3295 [SCOI2016]萌萌哒 题面 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \cdots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位, ...
- [bzoj4569][SCOI2016]萌萌哒-并查集+倍增
Brief Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两 ...
- 洛谷 3295 [SCOI2016]萌萌哒——并查集优化连边
题目:https://www.luogu.org/problemnew/show/P3295 当要连的边形如 “一段区间内都是 i 向 i+L 连边” 的时候,用并查集优化连边. 在连边的时候,如果要 ...
- BZOJ 4569: [Scoi2016]萌萌哒 [并查集 倍增]
传送门 题意:长为$n \le 10^5$的数字,给出$m \le 10^5$个限制$[l1,r1]\ [l2,r2]$两个子串完全相等,求方案数 把所有要求相等的位置连起来,不就是$9*10^{连通 ...
随机推荐
- HashMap的resize方法中尾部遍历出现死循环问题 Tail Traversing (多线程)
一.背景介绍: 在看HashMap源码是看到了resize()的源代码,当时发现在将old链表中引用数据复制到新的链表中时,发现复制过程中时,源码是进行了反序,此时是允许反序存储的,同时这样设计的效率 ...
- Kotlin入门(27)文件读写操作
Java的文件处理用到了io库java.io,该库虽然功能强大,但是与文件内容的交互还得通过输入输出流中转,致使文件读写操作颇为繁琐.因此,开发者通常得自己重新封装一个文件存取的工具类,以便在日常开发 ...
- 微软的wp版remotedesktop第三方库居然用了openssl和苹果的东西
微软的wp版remotedesktop居然用了openssl和苹果的东西,这真是想不通.不说openssl的漏洞问题,windows nt已经带了很全面的加解密api.
- 网络互联技术(2)——前篇—【转载】电脑结构和CPU、内存、硬盘三者之间的关系
原文链接:传送门 详细内容: 电脑结构和CPU.内存.硬盘三者之间的关系 前面提到了,电脑之父——冯·诺伊曼提出了计算机的五大部件:输入设备.输出设备.存储器.运算器和控制器. 我们看一下现在我们电脑 ...
- memory 监控 mysql vs percona vs maria
oracle mysql 5.7 在performance_schema 通过以下表展现内存信息.这些表实际engine为performance_schema.这些表数据实际是以数组的形式存储在内存中 ...
- AI学习---基于TensorFlow的案例[实现线性回归的训练]
线性回归原理复习 1)构建模型 |_> y = w1x1 + w2x2 + -- + wnxn + b 2)构造损失函数 | ...
- docker容器持久化卷讲解
docker容器自身存储数据效率比较低,因此我们为了提高磁盘IO的性能等,需要在容器中挂载一个外部存储设备.关于讲解大致如下: Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中 ...
- 第10章 嵌入式Linux 的调试技术
10.1 打印内核调试信息:printk printk位函数运行在内核空间, printf函数运行在用户空间.也就是说,像Linux 驱动这样的Linux内核程序只能使用printk函数输出调试信息 ...
- 【算法】LeetCode算法题-Two Sum
程序 = 数据结构 + 算法. 算法是每一位程序员学习成长之路上无法避开的重要一环,并且越早接触越好.今后会每天做些算法题,至少每天做一道题目,同时会记录自己的解题思路和代码,通过[算法]专题来分享. ...
- 设计模式のFlyweight(享元模式)----结构模式
一.产生背景 享元模式:它使用共享物件,用来尽可能减少内存使用量以及分享资讯给尽可能多的相似物件:它适合用于只是因重复而导致使用无法令人接受的大量内存的大量物件.通常物件中的部分状态是可以分享.常见做 ...