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\) ...
随机推荐
- Python3入门(十)——调试与测试
一.异常处理 1.try...except...finally... 这个也就是Java里的try...cath..finally...了,直接看经典代码: try: print("开始执行 ...
- Sqlite 快速批量插入数据 测试
public static int insertDbBatch() { string sql = ""; SQLiteConnection conn = new SQLiteCon ...
- C# HtmlAgilityPack和AngleSharp 解析HTML
C# HtmlAgilityPack和AngleSharp 解析HTML by:wgscd date:2018-1-17 HtmlAgilityPack 有点是只有一个单独DLL.AngleShar ...
- WPF编程,C#中对话框自动关闭的一种方法。
原文:WPF编程,C#中对话框自动关闭的一种方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_43307934/article/details/8 ...
- ubuntu 12.04 桌面版关闭图形界面
对于12.04的ubuntu桌面系统,如果想在开机的时候直接进入字符界面,那可以: 编辑文件 /etc/init/lightdm.conf,在第12行附近,原句“ and runlevel [!06] ...
- RabbitMQ 汇总
<RabbitMQ Tutorial>译文 第 1 章 简介 <RabbitMQ Tutorial>译文 第 2 章 工作队列 <RabbitMQ Tutorial> ...
- phpmyadmin连接MySQL服务器被拒绝
显示: phpMyAdmin 尝试连接到MySQL服务器,但服务器拒绝连接.您应该检查配置文件中的主机.用户名和密码,并确认这些信息与 MySQL 服务器管理员所给出的信息一致. 原因: 可能是修改了 ...
- 开发工具之Spark程序开发详解
一 使用IDEA开发Spark程序 1.打开IDEA的官网地址,地址如下:http://www.jetbrains.com/idea/ 2.点击DOWNLOAD,按照自己的需求下载安装,我们用免费版 ...
- oracle创建用户和角色、管理授权以及表空间操作
show user 显示当前用户connect username/password@datebasename as sysdba 切换用户和数据库 和用户身份 Oracle登录身份有三种: norma ...
- ats 安全
Controlling Access ats可以配置为仅允许某些客户端使用代理缓存. 1. 为ip_allow.config添加一行,以获取允许访问ats的每个IP地址或IP地址范围; 2. traf ...