1 条题解
-
0
题目分析
我们有一个无限长的01序列,它由长度为的循环节重复构成。定义,其中是前个位置中1的个数。
我们需要处理两种查询:
- 找到序列中第大的值所在的位置
- 查询在序列中的排名(如果不存在则输出
inf)
比较规则: 或 ( 且 )
关键观察
1. 分数表示与比较
对于位置,有:
$$f_i = \frac{c_i}{i} = \frac{\lfloor \frac{i-1}{n} \rfloor \cdot c_n + c_{((i-1) \bmod n) + 1}}{i} $$定义,则比较和的大小等价于比较:
$$\frac{c_a}{a} \leq \frac{c_b}{b} \iff c_a \cdot b \leq c_b \cdot a \iff r_a \cdot b \leq r_b \cdot a $$2. 特殊性质
代码中的
flag变量标记了特殊情况:当所有时,即或序列具有特殊结构时,可以采用简化的计算方法。算法思路
高精度处理
由于可能达到,需要实现高精度整数类
Int:- 采用基数为的表示法
- 支持加、乘、除、取模等运算
查询类型1:找第k大的位置
特殊情况处理 (
flag = true)当所有时:
- 统计的位置数量
- 将大数分解为:
- 答案位置为
一般情况处理
- 统计所有的位置的之和
- 将分解为:
- 使用二分法找到满足条件的分数边界
- 在候选位置中找到第个位置
查询类型2:查询排名
特殊情况处理 (
flag = true)当时直接返回
inf,否则:- 统计的位置数量
- 计算位置在循环节中的排名
- 结合循环次数计算总排名
一般情况处理
- 如果,返回
inf - 将位置分解为在循环节中的信息
- 统计所有比大的分数个数
- 使用数学公式计算总排名
复杂度分析
- 预处理:计算前缀和和数组
- 每次查询:
- 高精度运算:与数字位数相关
- 二分查找:
- 候选位置排序:最坏
- 总体:由于,算法可以接受
代码实现要点
- 高精度类
Int:使用vector<ll>以为基数存储大整数 - 分数比较:通过交叉相乘避免浮点数精度问题
- 循环节处理:利用模运算将无限序列问题转化为有限问题
- 边界情况:特别注意和的情况
样例验证
对于样例1:
- 序列
100,,
查询结果与题目输出一致。
该算法通过数学分析和高效的高精度运算,成功解决了大规模数据下的排名查询问题。
- 1
信息
- ID
- 5453
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者