BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集
传送门
题解
ST表和并查集是我认为最优雅(其实是最好写……)的两个数据结构。
然鹅!他俩加一起的这道题,我却……没有做出来……
咳咳。
正解是这样的:
类似ST表有\(\log n\)层一样,我们开\(\log n\)个并查集。当已知\([l_1, r_1]\)和\([l_2, r_2]\)相同的时候,设\(j = \lfloor \log (r_1 - l_1 + 1) \rfloor\),把\(l_1, l_2\)在\(j\)这层的并查集中合并,把\(r_1 - 2^j + 1, r_2 - 2^j + 1\)也在\(j\)这层并查集中合并。
最后是要下放的。下方时,从大到小枚举\(j\),在\(j - 1\)这层并查集中合并\(i, fa[i][j]\)以及\(i + 2^{j - 1}, fa[i][j] + 2 ^ {j - 1}\)。
最后统计有多少不同的\(fa[i][0]\)即可,设有\(x\)个,则答案是\(9 * 10^{x - 1}\),因为第一位不能是0。
我犯了个低级失误,就是最后统计有多少不同的\(fa[i][0]\)时,我打的真的是\(fa[i][0]\),其实这里一定要findfa(i, 0)。。。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <ctime>
#include <cstdlib>
using namespace std;
typedef unsigned long long ll;
#define enter putchar('\n')
#define space putchar(' ')
template <class T>
void read(T &x){
char c;
bool op = 0;
while(c = getchar(), c > '9' || c < '0')
if(c == '-') op = 1;
x = c - '0';
while(c = getchar(), c >= '0' && c <= '9')
x = x * 10 + c - '0';
if(op) x = -x;
}
template <class T>
void write(T x){
if(x < 0) putchar('-'), x = -x;
if(x >= 10) write(x / 10);
putchar('0' + x % 10);
}
const int N = 100005, P = 1000000007;
int n, m, lg[N], fa[N][20];
bool vis[N];
ll ans = 9;
void init(){
for(int i = 1, j = 0; i <= n; i++)
lg[i] = i == (1 << (j + 1)) ? ++j : j;
for(int j = 0; (1 << j) <= n; j++)
for(int i = 1; i + (1 << j) - 1 <= n; i++)
fa[i][j] = i;
}
int findfa(int u, int j){
return fa[u][j] == u ? u : fa[u][j] = findfa(fa[u][j], j);
}
void merge(int u, int v, int j){
if(findfa(u, j) != findfa(v, j))
fa[fa[v][j]][j] = fa[u][j];
}
void merge(int l1, int r1, int l2, int r2){
int j = lg[r1 - l1 + 1];
merge(l1, l2, j);
merge(r1 - (1 << j) + 1, r2 - (1 << j) + 1, j);
}
int main(){
read(n), read(m);
init();
while(m--){
int l1, r1, l2, r2;
read(l1), read(r1), read(l2), read(r2);
merge(l1, r1, l2, r2);
}
for(int j = lg[n]; j; j--)
for(int i = 1; i + (1 << j) - 1 <= n; i++){
merge(i, fa[i][j], j - 1);
merge(i + (1 << (j - 1)), fa[i][j] + (1 << (j - 1)), j - 1);
}
for(int i = 1; i <= n; i++)
vis[findfa(i, 0)] = 1;
for(int i = 1, fir = 1; i <= n; i++)
if(vis[i]){
if(fir) fir = 0;
else ans = ans * 10 % P;
}
write(ans), enter;
return 0;
}
BZOJ 4569 [Scoi2016]萌萌哒 | ST表 并查集的更多相关文章
- BZOJ 4569 [Scoi2016]萌萌哒 ——ST表 并查集
好题. ST表又叫做稀疏表,这里利用了他的性质. 显然每一个条件可以分成n个条件,显然过不了. 然后发现有许多状态是重复的,首先考虑线段树,没什么卵用. 然后ST表,可以每一层表示对应的区间大小的两个 ...
- 【BZOJ 4569】 4569: [Scoi2016]萌萌哒 (倍增+并查集)
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 865 Solved: 414 Description 一个长 ...
- 【BZOJ-4569】萌萌哒 ST表 + 并查集
4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 459 Solved: 209[Submit][Status] ...
- bzoj 4569 [Scoi2016]萌萌哒 并查集 + ST表
题目链接 Description 一个长度为\(n\)的大数,用\(S_1S_2S_3...S_n\)表示,其中\(S_i\)表示数的第\(i\)位,\(S_1\)是数的最高位,告诉你一些限制条件,每 ...
- bzoj4569: [Scoi2016]萌萌哒(ST表+并查集)
好喵喵的题 将一个要求用ST表分割成logn个要求,如果把f[i][j]和f[u][v]在同一个集合,那么f[i][j-1]和f[u][v-1],f[i+2^(j-1)][j-1]和f[u][u+2^ ...
- bzoj 4569: [Scoi2016]萌萌哒
Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条 件表示为四个数,l1,r1,l2,r2,即两个长度相同的 ...
- BZOJ4569 SCOI2016萌萌哒(倍增+并查集)
一个显然的暴力是用并查集记录哪些位之间是相等的.但是这样需要连nm条边,而实际上至多只有n条边是有用的,冗余过多. 于是考虑优化.使用类似st表的东西,f[i][j]表示i~i+2^j-1与f[i][ ...
- 洛谷P3295 [SCOI2016]萌萌哒(倍增+并查集)
传送门 思路太妙了啊…… 容易才怪想到暴力,把区间内的每一个数字用并查集维护相等,然后设最后总共有$k$个并查集,那么答案就是$9*10^{k-1}$(因为第一位不能为0) 考虑倍增.我们设$f[i] ...
- [SCOI2016]萌萌哒(倍增+并查集)
当区间\([a,b]\)和\([c,d]\)对应相等时. 我们把两个区间对应位置上的数所在并查集合并. 最后并查集的数量为\(num\)答案就是\(9*10^num\)因为是个数,不能有前置\(0\) ...
随机推荐
- Java基础—基础语法与常用命令
一.基础语法 1.case不加break会有穿透效果 根据阿里规范,严禁省略default语句,即使它一句话也没有 2.for循环执行顺序: for(初始化1;条件2;迭代运算3){ 循环体4: } ...
- 20155239吕宇轩《网络对抗》Exp3 免杀原理与实践
20155239吕宇轩<网络对抗>Exp3 免杀原理与实践 实验过程 Kali使用上次实验msfvenom产生后门的可执行文件,上传到老师提供的网址http://www.virscan.o ...
- 12、JAVA内存模型与线程
一.JMM 有序性,可见性,原子性 synchorize :3个性都有: volatile:保证可见性+禁止指令重排: 二.线程的五种状态 面向过程与面向对象的差别 面向过程:站在计算机的角度分析和解 ...
- Visual Studio Package 插件开发(Visual Studio SDK)
背景 这段时间公司新做了一个支付系统,里面有N个后台服务,每次有更新修改,拷贝打包发布包“不亦乐乎”...于是我想要不要自己定制个打包插件. 部分朋友可能会认为,有现成的可以去找一个,干嘛不用持续集成 ...
- [摘抄]从 GitHub 身上学到的 3 个创业经验
1.找一个大问题去解决 让 Git 更容易使用是 GitHub 的目标,但它从来不是 GitHub 的最终目标.GitHub 的真正目标是让协作和编写软件变得更容易.世界上每一个软件开发者都在努力解决 ...
- 虚拟机console基础环境部署——工作目录准备
1. 概述2. 相关约定2.1 删除旧文件2.2 创建全局共享文件目录2.3 创建全局软件安装目录2.4 创建数据放置目录3. 总结 1. 概述 上述博客中,已经为console最小化安装了操作系统. ...
- 外网主机访问虚拟机下的web服务器(NAT端口转发)-----端口映射
主机:系统win7,ip地址172.18.186.210 虚拟机:VMware Workstation 7,虚拟机下安装了Centos操作系统,ip地址是192.168.202.128,部署了LAMP ...
- Nginx 配置高可用
阅读本文需要安装Nginx 一 什么是高可用 nginx作为负载均衡服务器 所有请求都到了nginx 可见nginx处于非常重要的位置 如果nginx服务器宕机 后端web服务器将无法提供服务 影响严 ...
- Airmon-ng抓包&破解wifi
安装 aircrack获取(aircrack源) sudo apt-get install aircrack-ng 配置 安装组件 sudo apt-get install build-essent ...
- 【大数据实战】将普通文本文件导入ElasticSearch
以<刑法>文本.txt为例. 一.格式化数据 1,首先,ElasticSearch只能接收格式化的数据,所以,我们需要将文本文件转换为格式化的数据---json. 下图为未处理的文本文件. ...