传送门


一个朴素的做法就是暴力连边并查集,可是这是\(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表优化连边的更多相关文章

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

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

  2. 洛谷P3295 萌萌哒 并查集 + ST表

    又切一道紫题!!! 成功的(看了一吨题解之后),我A掉了第二道紫题. 好,我们仔细观察,发现这是一个排列组合问题. 有些限定条件,要相等的地方,我们就用并查集并起来.最后一查有多少个并查集,就有多少个 ...

  3. luogu3295 萌萌哒 (并查集+ST表)

    如果给相同的位置连边,最后联通块数是n,最后答案就是$9*10^{n-1}$ 但直接连边是$O(n^2)$的 所以事先处理出一个ST表,每次O(1)地给那个ST表连边 最后再一点一点下放,就是把在这层 ...

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

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

  5. 2018.09.25 codeforces1053E. Euler tour(并查集+st表+模拟)

    传送门 毒瘤细节题. 首先考虑不合法的情况. 先把相同的值配对,这样就构成了一些区间. 那么如果这些区间有相交的话,就不合法了. 如何判断?DZYO安利了一波st表,我觉得很不错. 接着考虑两个相同的 ...

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

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

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

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

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

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

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

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

随机推荐

  1. 转载------35岁开始转变的观念(干了这碗鸡汤再写代码保证没有bug)

    作为一个标准的IT男,从一开始的一线开发,做到管理层,又因为喜爱开发,跳槽继续专注coding,一干就是10多年.有时候就想,这样一直学习,coding,如果能干到老也挺不错的! 不过生活的压力是不会 ...

  2. 改变RadioButton的文字位置以及距离

    在默认情况下,RadioButton的 文字位置和文字的距离是不变的,为了可以改变它,我们可以用以下的方法. 1.改变文字的位置 android:button="@null" // ...

  3. Unity编译时找不到AndroidSDK的问题 | Unable to list target platforms(转载)

    原文:http://www.jianshu.com/p/fe4c334ee9fe 现象 在用 Unity 编译 Android 平台的应用时,遇到 Unable to list target plat ...

  4. css和HTML布局小技巧

    一:水平居中 1. 如下所示,让child在parent中水平居中 <!DOCTYPE html> <html> <head lang="en"> ...

  5. mysql之事务管理

    本文内容: 什么是事务管理 事务管理操作 回滚点 默认的事务管理 首发日期:2018-04-18 什么是事务管理: 可以把一系列要执行的操作称为事务,而事务管理就是管理这些操作要么完全执行,要么完全不 ...

  6. Python笔记(十五):匿名函数和@property

    (一)匿名函数 不想显式定义函数的时候,可以使用匿名函数. def f(x): return x*x #将匿名函数赋值给一个变量 result = lambda x:x*x print(result( ...

  7. DataGridView的单元格如何嵌入多个按钮控件

    前段时间我有一个朋友面试公司的时候遇到这个面试题,他也给了份原题给我瞧瞧,并没有什么特别的要点,关于这一类问题,如何在网格上的单元格嵌入多个控件(如按钮.超链接等)问题,我在网上搜索了下这类问题,发现 ...

  8. UnrealEd3视图导航及常用快捷键

    本博客使用的版本:2010-08   [更多其他的UE3版本][tps所用版本: 2011-02]     [最新的UE3版本 -- 2015-02] [unreal engine wiki  中文w ...

  9. Spark MLlib线性回归代码实现及结果展示

    线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析. 这种函数是一个或多个称为回归系数的模型参数的线性组合.只有 ...

  10. SQL Server Alert发送告警邮件少了的原因

    最近突然发现我们部署在数据库上面的告警(Alert),当错误日志里面出现错误时,并不是每个错误日志都会发送邮件出来.如下所示,设置了告警"SQL Server Severity Event ...