http://www.lydsy.com/JudgeOnline/problem.php?id=4569

用ST表表示所有区间,根据ST表中表示的区间长度种一棵nlogn的树,类似线段树,每个节点的左孩子和右孩子表示的区间拼接起来的总区间即为这个节点表示的区间。树上同一层节点表示的区间长度相同,同一层节点就可以用并查集来维护。

这样对于m个限制,用ST表把每个限制中的区间拆成前一块和后一块两块,限制中要求相同的两个区间的前一块和后一块分别用并查集合并,可以满足这两个区间完全相同。

最后从树的顶部(树根可能有很多)逐层下推就可以啦(把这一层两个区间相同的信息下推到这两个区间在下一层中的前一块相同并且后一块相同)~~~推到最底层统计有多少个不相同的数字,(个数-1)×10×9即为答案。

时间复杂度$O(n\log na(n)+ma(n))$

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100003;
int in() {
int k = 0, fh = 1; char c = getchar();
for(; c < '0' || c > '9'; c = getchar())
if (c == '-') fh = -1;
for(; c >= '0' && c <= '9'; c = getchar())
k = (k << 3) + (k << 1) + c - '0';
return k * fh;
} int n, m, f[N][18], cnt, lson[N * 18], rson[N * 18], fa[N * 18], Log_2[N]; void init() {
cnt = 0;
for(int i = 1; i <= n; ++i) {
if ((1 << (cnt + 1)) <= i) ++cnt;
Log_2[i] = cnt;
}
cnt = 0;
for(int j = 0; (1 << j) <= n; ++j)
for(int i = 1; i + (1 << j) - 1 <= n; ++i) {
f[i][j] = ++cnt;
lson[cnt] = f[i][j - 1];
rson[cnt] = f[i + (1 << (j - 1))][j - 1];
}
for(int i = 1; i <= cnt; ++i) fa[i] = i;
} int find(int a) {
if (fa[a] == a) return a;
fa[a] = find(fa[a]); return fa[a];
}
void merge(int a, int b) {
a = find(a); b = find(b);
if (a != b) fa[a] = b;
} int main() {
n = in(); m = in();
init();
int len, x1, y1, x2, y2;
while (m--) {
x1 = in(); y1 = in(); x2 = in(); y2 = in();
len = Log_2[y1 - x1 + 1];
merge(f[x1][len], f[x2][len]);
merge(f[y1 - (1 << len) + 1][len], f[y2 - (1 << len) + 1][len]);
} int t;
for(int i = cnt; i > n; --i)
if ((t = find(i)) != i) {
merge(lson[i], lson[t]);
merge(rson[i], rson[t]);
} t = 0;
for(int i = 1; i <= n; ++i)
if (find(i) == i) ++t;
int ret = 9;
while (--t) ret = (int) (1ll * ret * 10 % 1000000007);
printf("%d\n", ret);
return 0;
}

对于区间相同之类的限制,即区间操作,线段树往往是十分强大的。但也有线段树解决不了的题,就像这道题,因为线段树表示区间的logn个节点是"不规则的",随区间位置的改变而变化,这样对于两个不同位置相同长度的区间就很难用并查集来维护了。没有区间修改操作时,ST表表现的十分优越,不仅可以$O(1)$回答可合并信息,而且可以快速的且有规律的将区间"剖分",结合其他数据结构很方便地维护两个长度相同的区间之间的关系。

【BZOJ 4569】【SCOI 2016】萌萌哒的更多相关文章

  1. SCOI 2016 萌萌哒

    SCOI 2016 萌萌哒 solution 有点线段树的味道,但是并不是用线段树来做,而是用到另外一个区间修改和查询的利器--ST表 我们可以将一个点拆成\(logN\)个点,分别代表从点\(i\) ...

  2. [Luogu P3295][SCOI 2016]萌萌哒

    先说下暴力做法,如果[l1,r1]和[l2,r2]子串相等等价于两个区间内每个数对应相等.那么可以用并查集暴力维护,把对应相等的数的位置维护到同一个集合里去,最后答案其实就是把每个集合可以放的数个数乘 ...

  3. bzoj 4568 [SCOI 2016] 幸运数字

    题目大意 给定一棵\(n\)个点的树,每个点有权值 \(q\)次询问树上路径中 每个点权值可选可不选的最大异或和 \(n\le 2*10^4,q\le 2*10^5,val[i]\le 2^{60}\ ...

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

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

  5. [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分

    [LOJ 2083][UOJ 219][BZOJ 4650][NOI 2016]优秀的拆分 题意 给定一个字符串 \(S\), 求有多少种将 \(S\) 的子串拆分为形如 AABB 的拆分方案 \(| ...

  6. [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)

    [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...

  7. BZOJ 4569 萌萌哒

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

  8. 【BZOJ 4568】【SCOI 2016】幸运数字

    写了一天啊,调了好久,对拍了无数次都拍不出错来(数据生成器太弱了没办法啊). 错误1:把线性基存成结构体,并作为函数计算,最后赋值给调用函数的变量时无疑加大了计算量导致TLE 错误2:像这种函数(A, ...

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

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

随机推荐

  1. 洛谷P1141 01迷宫

    题目描述 有一个仅由数字0与1组成的n×n格迷宫.若你位于一格0上,那么你可以移动到相邻4格中的某一格1上,同样若你位于一格1上,那么你可以移动到相邻4格中的某一格0上. 你的任务是:对于给定的迷宫, ...

  2. Java中的移位运算符

    java中有三种移位运算符 <<      :     左移运算符,num << 1,相当于num乘以2 >>      :     右移运算符,num >& ...

  3. HOLOLENS的DEVICE POTAL连接和安装

    首先进入HOLOLENS, SETTINGS -> ADVACEED SETTING (一行小蓝字)点击 里面有它的IP 然后在开发机的浏览器里输入这个IP,会显示证书有误 然后进去后要下载一个 ...

  4. python pip install mysql-connector-python

    sudo pip install mysql-connector-python 报错信息:Collecting mysql-connector-python Could not find a vers ...

  5. 初识hibernate框架之一:进行简单的增删改查操作

    Hibernate的优势 l 优秀的Java 持久化层解决方案  (DAO) l 主流的对象—关系映射工具产品 l 简化了JDBC 繁琐的编码 l 将数据库的连接信息都存放在配置文件 l 自己的ORM ...

  6. maven-安装配置

    Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. maven是什么maven这个词可以翻译为“知识的积累”,也可以翻译为“专家”或“内行” ...

  7. java 22 - 16 多线程之生产者和消费者的问题

    生产者和消费者问题的描述图 通过上图,我们可以发现: 生产者和消费者使用的都是同一个资源(肉包子) 所以,当使用线程的时候,这两类的锁也是同一把锁(为了避免出现线程安全问题) 例子:学生信息的录入和获 ...

  8. 修复垂直滑动RecyclerView嵌套水平滑动RecyclerView水平滑动不灵敏问题

    在 Android 应用中,大部分情况下都会使用一个垂直滚动的 View 来显示内容(比如 ListView.RecyclerView 等).但是有时候你还希望垂直滚动的View 里面的内容可以水平滚 ...

  9. js删除数据的几种方法

    js 删除数组几种方法 var arr=['a','b','c']; 若要删除其中的'b',有两种方法: 1.delete方法:delete arr[1] 这种方式数组长度不变,此时arr[1]变为u ...

  10. Symbol ES6 新增的一种值类型数据,表示一种绝不重复的值

    let s1 = Symbol(33); let s2 = Symbol(33); alert(typeof(s1)); //数据类型判断 // alert(s1.toString()); //可把一 ...