洛谷 P9683 A Certain Forbidden Index 题解
题目链接:\(\color{Purple}\texttt{P9683 A Certain Forbidden Index}\)。
填坑。提供一个相对好写的做法。
考虑把一堆不交的区间绑在一起问(即先询问这些区间的并,判断答案是否在里面):对于一个区间,能与它绑在一起的区间最多只有 \(1\) 个是与它同一层的。
于是我们想到一个比较原始的做法:因为 \([1,2^k]\) 没有任何区间可以合并,所以放最后作为单独一块问;从线段树的顶端按照 BFS 序往下询问,如果该区间 \([l,r]\) 没有进行过标记(记这种区间为“初始区间”),按以下方式处理:标记它,如果它是作为左儿子被问到的(反之同理),那么就不断往右找下一层且它们的并集是一个区间的区间 \([l_1,r_1]\)(即满足 \(l_1=r+1\)),然后 \([l,r]\leftarrow[l_1,r_1]\),对 \([l_1,r_1]\) 进行标记;这样能获得不少的块并且答案已经很优。加上对 \(k=1\) 的特判可以做到 \(63\mathrm{pts}\):笔者考场上使用的是该做法,已经得到了一个非常可观的分数。
注:对于这种做法,如果对块内相邻元素连边,在整棵线段树上这些边就可以构成很多交叉的 X 型(读者可以自行理解一下)。
但是此时答案还不是最优的。考虑是否可以合并一些区间:我们观察到,对于一些左 / 右端点在正中间的作为右 / 左儿子进行处理的区间,是可以将它所在的块和同一层那个唯一可以合并的区间所在的块合并的。例如,\(k=4\) 时,区间 \([7,8]\) 与区间 \([9,10]\) 所在的块可以合并。处理的过程中考虑一下这种情况。
事实上我们可以观察到,对于合并同一层的这种情况,我们只需处理 \([l,r]\) 满足 \(r<2^k\) 且作为右儿子询问到的“初始区间”所在的块和它右边那个同层的且可合并的区间所在的块即可。证明显然。
询问块内元素的过程可以不用像其他题解一样用二分,因为我们观察到如果一个块的大小如果不超过 \(2\),那么二分跟朴素做法的没有区别——实际上块越小两种做法的区别越小。又因为是按照 BFS 序从上往下问,感性理解一下就可以得知越往下问块越小而且数量越多。实测可以获得 \(100\mathrm{pts}\)。
如果不放心可以把所有块全部预处理出来然后按照块的大小降序排序询问。但是这个做法会在 \(k=14\) 的时候超时,所以选用前者。
示例代码(\(100\mathrm{pts}\)):
#include<bits/stdc++.h>
using namespace std;
typedef pair<int,int> pii;
int query(int,int);
pii solve(int k){
vector<tuple<int,int,int,int> > q;
function<void(int,int,int)> dfs=[&](int l,int r,int w){
if(l==r)return;
q.emplace_back(l,l+r>>1,w-1,0);
q.emplace_back(l+r+1>>1,r,w-1,1);
dfs(l,l+r>>1,w-1);
dfs(l+r+1>>1,r,w-1);
}; // 按照 BFS 序处理出所有区间遍历顺序,0/1 表示左 / 右儿子
dfs(1,1<<k,k);
set<pii> t; t.emplace(1,1<<k);
vector<tuple<vector<pii>,int,int,int,int> > s;
for(auto [l,r,w,b]:q){
if(t.find(make_pair(l,r))==t.end()){
vector<pii> v; int p=(b?l:r);
for(int i=w-1;i>=0;i--){
v.emplace_back(b?p-(1<<i):p+1,b?p-1:p+(1<<i));
b?p-=(1<<i):p+=(1<<i);
} // 处理块
if(b){
bool b2=false;
if(r<(1<<k)){
b2=true,p=r;
for(int i=w;i>=0;i--){
v.emplace_back(p+1,p+(1<<i));
p+=(1<<i);
}
} // 可以与同一层的合并
if(query(l-(1<<w)+1,b2?(r<<1)-l+(1<<w):r)){
// 询问是否在整个区间,下同
for(auto [l1,r1]:v)
if(query(l1,r1))return make_pair(l1,r1);
// 询问单个区间,下同
return make_pair(l,r);
// 不在上述区间就是最后一个,下同
}
}
else if(query(l,r+(1<<w)-1)){
for(auto [l1,r1]:v)
if(query(l1,r1))return make_pair(l1,r1);
return make_pair(l,r);
}
for(auto [l1,r1]:v)t.emplace(l1,r1);
t.emplace(l,r); // 使用 std::set 打标记
}
}
return make_pair(1,1<<k); // 都不是上述区间
}
洛谷 P9683 A Certain Forbidden Index 题解的更多相关文章
- 洛谷P1854 花店橱窗布置 分析+题解代码
洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...
- HAOI2006 (洛谷P2341)受欢迎的牛 题解
HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...
- 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)
洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...
- 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)
洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...
- BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...
- 洛谷1578:[WC2002]奶牛浴场——题解
https://www.luogu.org/problemnew/show/P1578#sub 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建 ...
- 洛谷P2460 [SDOI2007]科比的比赛(题解)(贪心+搜索)
科比的比赛(题解)(贪心+搜索) 标签:算法--贪心 阅读体验:https://zybuluo.com/Junlier/note/1301158 贪心+搜索 洛谷题目:P2460 [SDOI2007] ...
- 洛谷 P1146 【硬币翻转】题解
很久很久之前做过的一道题 翻n-1枚硬币,就是有一枚不翻,也可以理解为翻一枚 直接上程序,看程序说话 #include<iostream> using namespace std; ; b ...
- 洛谷P1972 [SDOI2009]HH的项链 题解
[SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...
- 洛谷 p1352 没有上司的舞会 题解
P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...
随机推荐
- CAP 8.0 版本发布通告 - CAP 7岁生日快乐!
前言 今天,我们很高兴宣布 CAP 发布 8.0 版本正式版,从 2016 年 12 月 14 日CAP立项到 2023 年 12 月14 日发布 8.0 版本刚好满 7 年,祝 CAP 7 岁生日快 ...
- 【C#】【串口通信(Serial Port)】无法使用(using System.IO.Ports;)命名空间<Error:SerialPort不存在上下文>
1.包缺失导致--安装相应包: 2.等待命令行初始化--输入命令: Install-Package Microsoft.Windows.Compatibility -Version 5.0.2 参考网 ...
- 使用kubeadm在Centos8上部署kubernetes1.18
// 查看系统版本 cat /etc/centos-release CentOS Linux release 8.1.1911 (Core) // 如果系统环境为8.0(云服务器默认最大安装环境为8. ...
- 38. 干货系列从零用Rust编写负载均衡及代理,负载均衡中ip通行与禁止
wmproxy wmproxy已用Rust实现http/https代理, socks5代理, 反向代理, 静态文件服务器,四层TCP/UDP转发,七层负载均衡,内网穿透,后续将实现websocket代 ...
- STM32CubeMX教程13 ADC - 单通道转换
1.准备材料 开发板(正点原子stm32f407探索者开发板V2.4) ST-LINK/V2驱动 STM32CubeMX软件(Version 6.10.0) keil µVision5 IDE(MDK ...
- 深入剖析 Linux Cgroups 子系统:资源精细管理
本章主要演示以下 cgroups 下各个 subsystem 的作用. 根据难易程度,依次演示了 pids .cpu 和 memory 3 个 subsystem 的使用. 注:本文所有操作在 Ubu ...
- linux中mysql下载安装部署
创建mysql文件 mkdir mysql 首先通过yum下载wget命令 yum -y install wget 在mysql文件中通过wget下载MySQL存储库 wget https://dev ...
- 玩转云上数据湖,解析Serverless 技术落地
导读: 本文主要介绍Serverless计算相关技术与其在华为云数据湖探索服务(后文简称DLI)中的技术落地.Serverless是DLI将计算能力服务化和产品化关键技术,与传统IAAS和PAAS技术 ...
- 理解三值逻辑与NULL,你离SQL高手更近了一步
什么是NULL NULL 用于表示缺失的值或遗漏的未知数据,不是某种具体类型的值.数据表中的 NULL 值表示该值所处的字段为空,值为 NULL 的字段没有值,尤其要明白的是:NULL 值与 0 或者 ...
- Python 初学者必看:Python 异常处理集合
摘要:作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,本文专门介绍 python 异常处理. 异常 广义上的错误分为错误和异常 错误指的是可以人为避免 异常是指在语 ...