传送门

BZOJ 4569

题解

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表 并查集的更多相关文章

  1. BZOJ 4569 [Scoi2016]萌萌哒 ——ST表 并查集

    好题. ST表又叫做稀疏表,这里利用了他的性质. 显然每一个条件可以分成n个条件,显然过不了. 然后发现有许多状态是重复的,首先考虑线段树,没什么卵用. 然后ST表,可以每一层表示对应的区间大小的两个 ...

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

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

  3. 【BZOJ-4569】萌萌哒 ST表 + 并查集

    4569: [Scoi2016]萌萌哒 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 459  Solved: 209[Submit][Status] ...

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

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

  5. 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^ ...

  6. bzoj 4569: [Scoi2016]萌萌哒

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

  7. BZOJ4569 SCOI2016萌萌哒(倍增+并查集)

    一个显然的暴力是用并查集记录哪些位之间是相等的.但是这样需要连nm条边,而实际上至多只有n条边是有用的,冗余过多. 于是考虑优化.使用类似st表的东西,f[i][j]表示i~i+2^j-1与f[i][ ...

  8. 洛谷P3295 [SCOI2016]萌萌哒(倍增+并查集)

    传送门 思路太妙了啊…… 容易才怪想到暴力,把区间内的每一个数字用并查集维护相等,然后设最后总共有$k$个并查集,那么答案就是$9*10^{k-1}$(因为第一位不能为0) 考虑倍增.我们设$f[i] ...

  9. [SCOI2016]萌萌哒(倍增+并查集)

    当区间\([a,b]\)和\([c,d]\)对应相等时. 我们把两个区间对应位置上的数所在并查集合并. 最后并查集的数量为\(num\)答案就是\(9*10^num\)因为是个数,不能有前置\(0\) ...

随机推荐

  1. Java面试题,Java三大特性之一——多态的理解

    首先我们知道Java是一门面向对象的语言 面向对象三大特性,封装.继承.多态. 封装.继承.多态 ↓ 无论是学习路线,还是众人的口语习惯,都是按照这个这样进行排序,这是有原因的.因为封装好了才能继承, ...

  2. Wild Dog sample [sync data]

    <html> <head> <meta charset="UTF-8"> <title>test wilddog </titl ...

  3. 20155237 第十一周java课堂程序

    20155237 第十一周java课堂程序 内容一:后缀表达式 abcde/-f+ 内容二:实现Linux下dc的功能,计算后缀表达式的值 填充下列代码: import java.util.Scann ...

  4. Exp7 网络欺诈技术防范

    Exp7 网络欺诈技术防范 基础问题回答 1.通常在什么场景下容易受到DNS spoof攻击? 在同一局域网下比较容易受到DNS spoof攻击,攻击者可以冒充域名服务器,来发送伪造的数据包,从而修改 ...

  5. Js读取XML文件为List结构

    习惯了C#的List集合,对于Javascript没有list 极为不舒服,在一个利用Js读取XML文件的Demo中,决定自己构建List对象,将数据存入List. 第一步,Js读取XML文件知识 X ...

  6. MFC CHotKeyCtrl控件

    知识点: CHotKeyCtrl控件 获取热键数据 注册热键 响应热键事件 一.CHotKeyCtrl控件 void SetHotKey( WORD wVirtualKeyCode, WORD wMo ...

  7. Dynamics CRM Online Administrator password reset

    道道还挺多,好好看看 Dynamics CRM Online Administrator password reset

  8. 【HNOI2017】礼物

    题面 题解 显然两个手环只需要一个的亮度增加\(c \in [-m, m]\)和原题是等价的. 于是可以写成这样一个公式: \[ \sum_{i = 1} ^ n(x_i - y_{i+k} + c) ...

  9. 行级安全(Row-Level Security)

    通过授予和拒绝(Grant/Deny)命令控制用户的权限,只能控制用户对数据库对象的访问权限,这意味着,用户访问的粒度是对象整体,可以是一个数据表,或视图等,用户要么能够访问数据库对象,要么没有权限访 ...

  10. Qt QpushButton 实现长按下功能

    做项目需要一个按钮具备长时间按下的功能,才发现Qt原始的按钮是没有这个功能,不过Qt的原生按钮是存在按下和释放信号的,有了这两个信号,再来实现按钮长时间被按下,这就简单了,看下动画演示. 录成GIF效 ...