LOJ#2014「SCOI2016」萌萌哒(倍增,并查集优化连边)
题面
题意很明白,就不转述了吧。
题解
题目相当于告诉了我们若干等量关系,每个限制
l
1
,
r
1
,
l
2
,
r
2
\tt l_1,r_1,l_2,r_2
l1,r1,l2,r2 相当于
S
l
1
=
S
l
2
,
S
l
1
+
1
=
S
l
2
+
1
,
…
,
S
r
1
=
S
r
2
\tt S_{l_1}=S_{l_2},S_{l_1+1}=S_{l_2+1},\dots,S_{r_1}=S_{r_2}
Sl1=Sl2,Sl1+1=Sl2+1,…,Sr1=Sr2 这
r
1
−
l
1
+
1
r_1-l_1+1
r1−l1+1 个等量关系,每个等量关系把两个点绑在了一起。用并查集,把相等的点并起来,最终每个连通块内值相等,不同的块两两独立。
这样建边无疑是
n
2
\tt n^2
n2 级别的,远不能通过。但,一个有趣的现象是,最终实际存在在并查集中的边最多只有
n
−
1
\tt n-1
n−1 条。别的边到哪里去了呢?别的边的确没用,因此,如果能够尽量舍弃掉没用的边,那么解决这题就不在话下。
问题是,我们是不能提前知道每一条边是不是废边的。但同时,我们知道,经过并查集的算法过程,它会自然地并且神奇地把有用的边都给你留下来。
于是就有了这么一个做法:慢节奏合并并查集,过程中充分利用并查集筛选边的性质。
我们先用倍增思想,把每个限制
{
l
1
,
r
1
,
l
2
,
r
2
}
\tt \{l_1,r_1,l_2,r_2\}
{l1,r1,l2,r2} 变成两个长度为
2
k
\tt2^k
2k(选取使其不超过
[
l
1
,
r
1
]
\tt[l_1,r_1]
[l1,r1] 的长度并且最大化的
k
\tt k
k) 的限制:
{
l
1
,
r
1
,
l
1
+
2
k
−
1
,
r
1
+
2
k
−
1
}
\tt\{l_1,r_1,l_1+2^k-1,r_1+2^k-1\}
{l1,r1,l1+2k−1,r1+2k−1} 和
{
l
2
−
2
k
+
1
,
r
2
−
2
k
+
1
,
l
2
,
r
2
}
\tt\{l_2-2^k+1,r_2-2^k+1,l_2,r_2\}
{l2−2k+1,r2−2k+1,l2,r2} ,虽然有重,但是不影响。接着,把它们都放在限制集
b
u
[
k
]
\tt bu[k]
bu[k] 里待命。
然后,从大到小枚举
k
\tt k
k (
k
≤
log
n
\tt k\leq\log n
k≤logn)。每次,我们假定每个序列中的点
i
\tt i
i 代表着
[
i
,
i
+
2
k
−
1
]
\tt[i,i+2^k-1]
[i,i+2k−1] 这个大数区间,读取
b
u
[
k
]
\tt bu[k]
bu[k] 里每个元素
{
x
,
y
,
x
+
2
k
−
1
,
y
+
2
k
−
1
}
\tt\{x,y,x+2^k-1,y+2^k-1\}
{x,y,x+2k−1,y+2k−1} ,将点
x
\tt x
x 和点
y
\tt y
y 在并查集里合并,也就是意味着
[
x
,
x
+
2
k
−
1
]
\tt[x,x+2^k-1]
[x,x+2k−1] 和
[
y
,
y
+
2
k
−
1
]
\tt[y,y+2^k-1]
[y,y+2k−1] 两个区间的大数都对应相等。
在枚举到
k
′
\tt k'
k′ 之前,并查集里已经有的边,就是精简后的了。一开始,并查集里形如
(
x
,
y
)
\tt(x,y)
(x,y) 的边还代表着
[
x
,
x
+
2
k
′
+
1
−
1
]
\tt[x,x+2^{k'+1}-1]
[x,x+2k′+1−1] 和
[
y
,
y
+
2
k
′
−
1
−
1
]
\tt[y,y+2^{k'-1}-1]
[y,y+2k′−1−1] 相等,到这一层,就得代表
[
x
,
x
+
2
k
′
−
1
]
\tt[x,x+2^{k'}-1]
[x,x+2k′−1] 和
[
y
,
y
+
2
k
′
−
1
]
\tt[y,y+2^{k'}-1]
[y,y+2k′−1] 相等了,因此我们把它分裂为两条边
(
x
,
y
)
\tt(x,y)
(x,y) 和
(
x
+
2
k
′
,
y
+
2
k
′
)
\tt(x+2^{k'},y+2^{k'})
(x+2k′,y+2k′) ,再把多出的这条
(
x
+
2
k
′
,
y
+
2
k
′
)
\tt(x+2^{k'},y+2^{k'})
(x+2k′,y+2k′) 连到并查集里。
这样一来,一开始加的边是
O
(
n
)
\tt O(n)
O(n) 级别的,枚举时每一层加的边也是
O
(
n
)
\tt O(n)
O(n) 级别的,保留下来的边还是小于等于
n
−
1
\tt n-1
n−1 条。总共加的边最多就
n
log
n
\tt n\log n
nlogn 条,优化得非常到位。
这么个巧妙的做法,不知道当初第一个 AC 的人是怎么想出来的。这估计算是怎样解题里面说的U
n
b
e
l
i
e
v
a
b
l
e
!
\tt Unbelievable!
Unbelievable!一类题吧。
CODE
巧妙的做法往往代码简单。
#include<set>
#include<queue>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXN 100005
#define ENDL putchar('\n')
#define LL long long
#define DB double
#define lowbit(x) ((-x) & (x))
LL read() {
LL f = 1,x = 0;char s = getchar();
while(s < '0' || s > '9') {if(s=='-')f = -f;s = getchar();}
while(s >= '0' && s <= '9') {x=x*10+(s-'0');s = getchar();}
return f * x;
}
const int MOD = 1000000007;
int n,m,i,j,s,o,k;
struct it{
int l,r;it(){l=r=0;}
it(int L,int R){l=L;r=R;}
};
vector<it> bu[105];
int fa[MAXN];
int findf(int x) {return fa[x] == x ? x:(fa[x] = findf(fa[x]));}
void unionSet(int a,int b) {
int u = findf(a),v = findf(b);
if(u > v) swap(u,v);
fa[u] = v; return ;
}
bool ct[MAXN];
int main() {
n = read();m = read();
for(int i = 1;i <= n;i ++) {
fa[i] = i;
}
for(int i = 1;i <= m;i ++) {
s = read();int le = read() - s + 1;
o = read(); read();
int l2 = 0;
for(int j = 0;(1<<j) <= le;j ++) l2 = j;
bu[l2].push_back(it(s,o));
bu[l2].push_back(it(s+le-(1<<l2),o+le-(1<<l2)));
}
for(int i = 20;i >= 0;i --) {
for(int j = n;j > 0;j --) {
if(findf(j) != j) {
int k = findf(j);
if(k+(1<<i) <= n)
bu[i].push_back(it(j+(1<<i),k+(1<<i)));
}
}
for(int j = 0;j < (int)bu[i].size();j ++) {
s = bu[i][j].l,o = bu[i][j].r;
unionSet(s,o);
}
}
int ans = 1;
for(int i = 1;i <= n;i ++) {
if(!ct[findf(i)]) {
ct[findf(i)] = 1;
if(i == 1) ans = ans *9ll % MOD;
else ans = ans *10ll % MOD;
}
}
printf("%d\n",ans);
return 0;
}
LOJ#2014「SCOI2016」萌萌哒(倍增,并查集优化连边)的更多相关文章
- 【LOJ】#2014. 「SCOI2016」萌萌哒
题解 这个题好妙啊 首先我们发现,如果我们可以暴力,就是把相同的元素拿并查集合起来,最后统计集合个数\(cnt\) 答案是\(9\*10^{cnt - 1}\) 然而我们做不到= = 我们可以用倍增的 ...
- 「SCOI2016」萌萌哒 解题报告
「SCOI2016」萌萌哒 这思路厉害啊.. 容易发现有个暴力是并查集 然后我想了半天线段树优化无果 然后正解是倍增优化并查集 有这个思路就简单了,就是开一个并查集代表每个开头\(i\)每个长\(2^ ...
- loj#2013. 「SCOI2016」幸运数字 点分治/线性基
题目链接 loj#2013. 「SCOI2016」幸运数字 题解 和树上路径有管...点分治吧 把询问挂到点上 求出重心后,求出重心到每个点路径上的数的线性基 对于重心为lca的合并寻味,否则标记下传 ...
- loj#2015. 「SCOI2016」妖怪 凸函数/三分
题目链接 loj#2015. 「SCOI2016」妖怪 题解 对于每一项展开 的到\(atk+\frac{dnf}{b}a + dnf + \frac{atk}{a} b\) 令$T = \frac{ ...
- loj#2016. 「SCOI2016」美味
题目链接 loj#2016. 「SCOI2016」美味 题解 对于不带x的怎么做....可持久化trie树 对于带x,和trie树一样贪心 对于答案的二进制位,从高往低位贪心, 二进制可以表示所有的数 ...
- loj#2012. 「SCOI2016」背单词
题目链接 loj#2012. 「SCOI2016」背单词 题解 题面描述有点不清楚. 考虑贪心 type1的花费一定不会是优的,不考虑, 所以先把后缀填进去,对于反串建trie树, 先填父亲再填儿子, ...
- 「SCOI2016」萌萌哒
「SCOI2016」萌萌哒 题目描述 一个长度为 \(n\) 的大数,用 \(S_1S_2S_3 \ldots S_n\) 表示,其中 \(S_i\) 表示数的第 \(i\) 位,\(S_1\) 是数 ...
- loj #2013. 「SCOI2016」幸运数字
#2013. 「SCOI2016」幸运数字 题目描述 A 国共有 n nn 座城市,这些城市由 n−1 n - 1n−1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个幸运数字,以 ...
- 【BZOJ4569】[Scoi2016]萌萌哒 倍增+并查集
[BZOJ4569][Scoi2016]萌萌哒 Description 一个长度为n的大数,用S1S2S3...Sn表示,其中Si表示数的第i位,S1是数的最高位,告诉你一些限制条件,每个条件表示为四 ...
随机推荐
- 2022年Web前端开发流程和学习路线(详尽版)
前言 前端侧重于人机交互和用户体验,后端侧重于业务逻辑和大规模数据处理.理论上,面向用户的产品里,所有问题(包括产品.设计.后端.甚至看不见的问题)的表现形式,都会暴露在前端,而只有部分问题(数据问题 ...
- 开发工具-MySQL下载地址
更新记录 2022年6月10日 完善标题. 商业版下载 商业版下载地址 https://edelivery.oracle.com/ 使用Oracle账号登录即可下载. 官方下载 https://dev ...
- ASP.NET Core 应用配置指定地址和端口
更新记录 本文迁移自Panda666原博客,原发布时间:2021年5月10日. 几种方式 ASP.NET Core 应用配置指定地址和端口支持以下几种主要方式: 1.在命令行模式启动应用时设置 --u ...
- 这个Spring Security登录插件牛啊,验证码、小程序、OAuth2都能快速接入
上次我们把验证码登录.小程序登录优雅地集成到了Spring Security,很多同学大呼过瘾,相比较一些传统玩法高级了很多.胖哥就赶紧抓住机会举一反三,把几个非标准的OAuth2也接入了进来,主要是 ...
- 20天等待,申请终于通过,安装和体验IntelliJ IDEA新UI预览版
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 关于IDEA的预览版 IDEA会启用新的UI,这事情之 ...
- 叮,GitHub 到账 550 美元「GitHub 热点速览 v.22.26」
作者:HelloGitHub-小鱼干 如果你关注 GitHub 官方动态,你会发现它们最近频频点赞世界各地开发者晒出的 GitHub $550 sponsor 截图,有什么比"白嫖" ...
- CANN算子:利用迭代器高效实现Tensor数据切割分块处理
摘要:本文以Diagonal算子为例,介绍并详细讲解如何利用迭代器对n维Tensor进行基于位置坐标的大批量数据读取工作. 本文分享自华为云社区<CANN算子:利用迭代器高效实现Tensor数据 ...
- 史上最全学习率调整策略lr_scheduler
学习率是深度学习训练中至关重要的参数,很多时候一个合适的学习率才能发挥出模型的较大潜力.所以学习率调整策略同样至关重要,这篇博客介绍一下Pytorch中常见的学习率调整方法. import torch ...
- MC34063降压电路
MC34063芯片由温度自动补偿功能的基准电压发生器.比较器.占空比可控振荡器. 触发器和大电流输出开关电路等组成,具有功能齐全.价格低廉.体积小.效率高.仅需少量外部元器件等优点,其主要特性如表所示 ...
- JDBC:Statement问题
1.Statement问题 2.解决办法:通过PreparedStatement代替 实践: package com.dgd.test; import java.io.FileInputStrea ...