首页 > 其他分享 >CF1466I The Riddle of the Sphinx

CF1466I The Riddle of the Sphinx

时间:2023-07-25 11:23:59浏览次数:30  
标签:Riddle Sphinx 前缀 二进制 res CF1466I 答案 当前 最大

基本思路

明示了在二进制下考虑问题,我们大体的思路就是从高往低依次确定最大的数二进制下每一位上的值。

以下所述的「前缀」均指一个二进制数从高位到低位的一部分,一个元素的「前 \(k\) 位」表示二进制从高位到低位的前 \(k\) 位,\(res\) 表示当前记录的最大前缀的长度。

先看看操作能干嘛,一是可以判断一个数和一个前缀的大小关系,二是在知道某数前 \(k\) 位的前提下可以得到第 \(k+1\) 位。

依次确定每个数的值肯定不行,我们要通过当前知道的最大前缀对不可能成为答案的数进行排除,在同一个数上过多地停留询问它的信息也是不好的,这样可能导致我们得到许多无用信息。

考虑这样的一个过程:扫一遍数组,每次更新一下当前的最长前缀,然后不论产没产生贡献都把它抛之脑后,相当于每个数最多对答案产生 \(1\) 位的贡献,反复进行多轮这样的操作直到得出答案。

构造解法

有没有一种构造完美契合上面的思路呢,答案是肯定的,具体来说我们维护一个栈,它需要满足以下条件:

  • 栈中元素个数 \(=res\)。
  • 栈中自底向上第 \(k\) 位元素的二进制前 \(k\) 位与当前最大前缀的前 \(k\) 位相同。

考虑如何在加入元素 \(a_i\) 的同时维护这个栈:

  • 如果 \(a_i\) 的前 \(res\) 位大于当前确定的最大前缀,弹栈,重复进行这个过程。
  • 如果 \(a_i\) 的前 \(res\) 位等于当前确定的最大前缀,确定 \(i\) 的第 \(res+1\) 位并更新最大前缀。
  • 如果 \(a_i\) 的前 \(res\) 位小于当前确定的最大前缀,跳过 \(a_i\)。

当一轮扫描结束后,我们得到了当前的可能最大前缀。

为什么是可能最大前缀?原因就是上述算法中我们为了避免过多地获取某一个数可能无用的信息,每一个数对于 \(res\) 最多只有 \(1\) 位的贡献。

例如假设当前的栈的状态是像这样的,标红的是给最大前缀产生过贡献的位:

\[\begin{matrix}10{\color{Red}1}0\\1{\color{Red}0}01\\{\color{Red}1}111\end{matrix} \]

怎么反例都是从题解嫖的啊

现在得到的最大前缀是 \(101\),然而最下面的元素显然有更大的前缀 \(111\)。

这种情况是十分好处理的,我们要求的是最大的前缀而不是最长的,为了保证正确性就算缩减这轮得出的最大前缀长度也是值得的。

栈顶到栈底顺序扫一遍维护:

  • 如果 \(a_i\) 的前 \(res\) 位大于最大前缀,说明上方的最大前缀是假的,弹栈直到 \(a_i\) 为栈顶并更新最大前缀。
  • 如果 \(a_i\) 的前 \(res\) 位小于最大前缀且不为栈顶,它一定不会成为答案也不会影响答案正确性人畜无害好可爱,取出但不更新最大前缀。
  • 如果 \(a_i\) 的前 \(res\) 位小于最大前缀且正好是栈顶,弹栈且更新最长前缀。

这样做完一遍之后可能最大前缀一定最大,把得出的最大前缀加入答案,把所有数减去最大前缀,反证可以证明此时剩下 \(>0\) 的数一定在栈中,反复执行以上过程直到得出答案。

分析每一轮中上述策略的操作次数,第一次扫描中弹栈每轮最多执行 \(n-res\) 次,每次加入一个元素需要 \(3\) 次询问,第二次从栈顶向下排除需要 \(res\) 次,总计 \(4n\) 次询问。除了第一轮外每次的 \(n\) 会变为上一轮的 \(res\),\(\sum res=b\),所以总询问次数时 \(4(n+b)\) 的。

优化

减少询问看看能在哪些操作上面动手脚,好像除了加入一个数时判定它是否小于当前最大前缀都是必需的,那就看啊可能把这个操作删去,在加入时只要不能弹栈就确定 \(res+1\) 位会不会对答案产生负面影响,答案自然是不会,因为小于的数要么被可能成为答案的数在加入时弹掉,要么在从栈顶开始考虑时被弹掉左右都对答案没啥影响,优化到 \(3(n-b)\) 次询问。

标签:Riddle,Sphinx,前缀,二进制,res,CF1466I,答案,当前,最大
From: https://www.cnblogs.com/hhaaiiyyee66/p/CF1466I.html

相关文章

  • 使用sphinx生成项目文档
    Sphinx是一个基于Python的文档生成工具,它可以将标记文本转换为各种格式的文档,包括HTML、PDF、EPUB等。Sphinx最初是为Python文档而开发的,但是它也可以用于其他类型的文档,例如API文档、技术文档、用户手册等。Sphinx的主要特点包括:支持多种标记语言,包括reStructuredText、Markdo......
  • sphinx索引文件进一步说明——最好是结合lucene一起看,直觉告诉我二者本质无异
    Sphinx使用的文件包括“sph”,“spa”,“spi”,“spd”,“spp”,“spm”,还有锁文件。其中sph是系统的配置文件。其它则为索引文件。.Spi文件:保存WordId及指向此WordId对应的文档信息在spd文件的指针。Spi文件在检索程序启动时完全加载入内存。Spi文件是分块的,块内排序,块之间也......
  • Github + Sphinx+Read the docs 实战入门指南(二)
    引言接上一篇Github+Sphinx+Readthedocs实战入门指南(一),这一篇主要讲解如何自动将指定文档内容部署到Readthedocs中。对于文档,一般有以下基本要求:只维护一份,其他地方自动同步更新可以根据代码注释,动态更新维护相应的API文档支持检索多版本之间的API接口动态查看......
  • Github + Sphinx+Read the docs 实战入门指南(三)
    引言接着上两篇文章Github+Sphinx+Readthedocs实战入门指南(一)Github+Sphinx+Readthedocs实战入门指南(二)我们已经成功地将Sphinx文档部署到了Readthedocs网站,但是这个文档,我们不想每次都要手动更新内容,想要的是:在更改仓库主分支时,自动将相关内容更新部署......
  • Github + Sphinx+Read the docs 实战入门指南(一)
    引言GithubGithub是一个托管网站,目前主要用来托管代码,当然托管其他的也可。但是网不好的小伙伴可以考虑使用Gitee作为平替。SphinxSphinx是什么?Sphinx是一个自动生成文档的工具,可以用简洁的语法快速生成优雅的文档。哪些场景要用Sphinx?如果想要写书,不想陷入复杂的......
  • sphinx使用初体验笔记
    1#安装2pipinstallsphinx-ihttps://pypi.tuna.tsinghua.edu.cn/simple34#更换国内源5清华源6pipconfigsetglobal.index-urlhttps://pypi.tuna.......
  • (转)sphinx安装配置手记
    ​​http://www.54chen.com/architecture/sphinx-install-and-configure-notes.html​​​出自俄罗斯的开源全文搜索引擎软件Sphinx,单一索引最大可......
  • 开源一体化文档编写工具sgml/sphinx/markdown各自的适用场景
    一体化文档编写工具主要有sgml(pg采用)和sphinx(python社区和readthedocs采用)两大类,官方文档推荐、索引全面,跟HTML高度雷同,当然也有一些采用markdown(githubwiki或非正......
  • Sphinx全文检索
    全文检索一、生活中的数据总体分为:结构化数据:指具有固定格式或有限长度的数据,如数据库,元数据等。非结构化数据:指没有固定格式或不定长的数据,如邮件,word文档等。非结构化数据......
  • 使用sphinx-doc优雅的书写html和项目介绍,包含restructureText常用语法
    ​​跳转到我的gitee直接下载测试项目​​​​​sphinx概述​​​​使用nginx配置静态页面展示sphinx-doc点击跳转​​系统:win10中WSL(Ubuntu18.04)编辑器:VScode插件:......