问题描述
试题编号: | 202112-2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
试题名称: | 序列查询新解 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
时间限制: | 1.0s | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
内存限制: | 512.0MB | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
问题描述: |
题目背景上一题“序列查询”中说道: 对于给定的序列 A 和整数 x,查询 f(x) 是一个很经典的问题,可以使用二分搜索在 O(logn) 的时间复杂度内轻松解决。但在 IT 部门讨论如何实现这一功能时,小 P 同学提出了些新的想法。 题目描述小 P 同学认为,如果事先知道了序列 A 中整数的分布情况,就能直接估计出其中小于等于 x 的最大整数的大致位置。接着从这一估计位置开始线性查找,锁定 f(x)。如果估计得足够准确,线性查找的时间开销可能比二分查找算法更小。 比如说,如果 A1,A2,⋯,An 均匀分布在 (0,N) 的区间,那么就可以估算出: 为了方便计算,小 P 首先定义了比例系数 r=⌊Nn+1⌋,其中 ⌊ ⌋ 表示下取整,即 r 等于 N 除以 n+1 的商。进一步地,小 P 用 g(x)=⌊xr⌋ 表示自己估算出的 f(x) 的大小,这里同样使用了下取整来保证 g(x) 是一个整数。 显然,对于任意的询问 x∈[0,N),g(x) 和 f(x) 越接近则说明小 P 的估计越准确,后续进行线性查找的时间开销也越小。因此,小 P 用两者差的绝对值 |g(x)−f(x)| 来表示处理询问 x 时的误差。 为了整体评估小 P 同学提出的方法在序列 A 上的表现,试计算: 输入格式从标准输入读入数据。 输入的第一行包含空格分隔的两个正整数 n 和 N。 输入的第二行包含 n 个用空格分隔的整数 A1,A2,⋯,An。 注意 A0 固定为 0,因此输入数据中不包括 A0。 输出格式输出到标准输出。 仅输出一个整数,表示 error(A) 的值。 样例1输入
Data 样例1输出
Data 样例1解释A=[0,2,5,8] r=⌊Nn+1⌋=⌊103+1⌋=2
样例2输入
Data 样例2输出
Data 样例3输入
Data 样例3输出
Data 样例3解释A=[0,1,3] r=⌊Nn+1⌋=⌊102+1⌋=3
子任务70% 的测试数据满足 1≤n≤200 且 n<N≤1000; 全部的测试数据满足 1≤n≤105 且 n<N≤109。 提示需要注意,输入数据 [A1⋯An] 并不一定均匀分布在 (0,N) 区间,因此总误差 error(A) 可能很大。 代码
优化要点:1.无须采用搜索或者单独遍历,fx的规律使得我们可以变读入边处理,使得循环次数减少 2.gx是一个周期为r的循环递增函数,对此我们可以以此计算出在该周期内值的乘积而不是逐个遍历相加,这可以进一步节省时间 |