题目链接:\(\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 题解的更多相关文章

  1. 洛谷P1854 花店橱窗布置 分析+题解代码

    洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...

  2. HAOI2006 (洛谷P2341)受欢迎的牛 题解

    HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...

  3. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

  4. 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)

    洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...

  5. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

  6. 洛谷1578:[WC2002]奶牛浴场——题解

    https://www.luogu.org/problemnew/show/P1578#sub 由于John建造了牛场围栏,激起了奶牛的愤怒,奶牛的产奶量急剧减少.为了讨好奶牛,John决定在牛场中建 ...

  7. 洛谷P2460 [SDOI2007]科比的比赛(题解)(贪心+搜索)

    科比的比赛(题解)(贪心+搜索) 标签:算法--贪心 阅读体验:https://zybuluo.com/Junlier/note/1301158 贪心+搜索 洛谷题目:P2460 [SDOI2007] ...

  8. 洛谷 P1146 【硬币翻转】题解

    很久很久之前做过的一道题 翻n-1枚硬币,就是有一枚不翻,也可以理解为翻一枚 直接上程序,看程序说话 #include<iostream> using namespace std; ; b ...

  9. 洛谷P1972 [SDOI2009]HH的项链 题解

    [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...

  10. 洛谷 p1352 没有上司的舞会 题解

    P1352 没有上司的舞会 题目描述 某大学有N个职员,编号为1~N.他们之间有从属关系,也就是说他们的关系就像一棵以校长为根的树,父结点就是子结点的直接上司.现在有个周年庆宴会,宴会每邀请来一个职员 ...

随机推荐

  1. Java并发(十九)----Monitor原理及Synchronized原理

    1.Java 对象头 以 32 位虚拟机为例 普通对象 |--------------------------------------------------------------| |       ...

  2. 实践解析HPA各关联组件扭转关系

    本文分享自华为云社区<HPA各关联组件扭转关系以及建议>,作者:可以交个朋友. 一.背景 应用程序的使用存在波峰波谷现象,在应用流量处于低谷期间,可以释放因过多的Pod而浪费的硬件资源.在 ...

  3. 深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs

    通过这篇文章你可以了解到 Docker 容器的核心实现原理,包括 Namespace.Cgroups.Rootfs 等三个核心功能. 如果你对云原生技术充满好奇,想要深入了解更多相关的文章和资讯,欢迎 ...

  4. 数字孪生和GIS系统融合能为水利领域带来什么改变?

    随着科技的不断进步,数字孪生和GIS系统的融合应用逐渐成为了水利领域的新趋势.数字孪生是指通过数字化技术模拟物理实体和过程,将现实世界与虚拟世界相结合的技术,而GIS系统则是地理信息系统,用于收集.存 ...

  5. 【C++】【图像处理】均值滤波 and 高斯滤波 and 中值滤波 (低通滤波器)and Sobel算子边缘提取算法解析(以.raw格式的图像为基础进行图像处理、gray levels:256)

    1 void meanFilter(BYTE* image, int width, int height, BYTE* outImg) 2 { 3 //均值滤波 4 int smth[9]; 5 in ...

  6. ElasticSearch之禁用交换分区

    操作系统将进程加载至内存中执行时,对于当前未使用到的内存页,可能会将相关内存页交换至硬盘上,即swap. 对于性能敏感.时延敏感的应用程序比如ElasticSearch,swap特性会明显影响性能和稳 ...

  7. 【李南江】从零玩转TypeScript

    前言 老套路肯定是 需要知道TS是干啥用的啦. 1.什么是TypeScript(TS)? TypeScript简称TS TS和JS之间的关系其实就是Less/Sass和CSS之间的关系 就像Less/ ...

  8. 使用gradle的方式进行Springboot3的web开发(微服务版)

    简要: 最近看了很多的Springboot3的项目,但是发现很多都是用maven来进行版本管理的,很少有用gradle来管理的,通过网上查找资料,看视频,终于自己写一个gradle管理的Springb ...

  9. Sliver 二开准备

    cs被杀麻了,最近打算看看一下sliver的源码进行一下二开,这篇是记录遇到的一些问题 编译sliver Windows下 官方说用MingW,但是我自己用他带的make不行, ​​ ‍ 下载make ...

  10. Linux应急响应总结——更新中

    Linux应急响应 用户信息 方向 查看可登录的用户: cat /etc/passwd | grep /bin/bash awk -F: '{if($7!="/usr/sbin/nologi ...