[Python与CSP的姻缘] 202112-2 序列查询新解

文章讲述了如何运用分块计算的思想解决一道编程题,该题涉及到序列查询的优化。由于直接遍历求解会超时,作者通过分析样例数据发现f和g值的分段特性,提出先按f的区间划分,再找g的区间端点,以确定一致区间并分段求解的方法。代码分别展示了未优化和优化后的解决方案,优化后的方案避免了遍历,提高了效率。
摘要由CSDN通过智能技术生成

题目

题目
样例1
样例2-3
子任务+提示

思路

这个题是跟这一年的第一题是相互关联的,第一题“序列查询”给出了分块计算的思想,这个题就延续下来继续来用了
要是按题目那么求f,遍历求解的话会超时,观察样例给出的f和g的数据,可以发现f和g的值都是按区间一段一段的,那么就是看怎么求出这个区间的长度
但是f和g的分段不是同步的,有交叉,那么就要先按一个区间走(比如说先按f的区间分),然后再在这个基础上看有没有g的区间的端点
找到f和g的一致区间后分段求解

这里可以发现,f的值可以从原数组直接看出,g每个段的长度是一样的,这样可以不用求f和g的数组,只需要求分段的长度就可以了

代码

70分

这是按题干给的求f的公式求的,需要遍历的话就会超时

import math
n,N = map(int,input().split())
A =[0] + list(map(int,input().split())) # 递增
fx = [0]*N
for x in range(N):
    tmp_index = (n+1)//N*x
    while tmp_index <=n and A[tmp_index]<=x:
        tmp_index += 1
    if tmp_index == n and A[tmp_index]<=x:
        fx[x] = tmp_index
    else:
        fx[x] = tmp_index-1
r = N//(n+1)
error = 0
g = [0]*N
for i in range(N):
    g[i] = i//r
    error += math.fabs(g[i]-fx[i])
print(int(error))

100分

借鉴第一题分段求的思想,关键是怎么去分段

n,N = map(int,input().split())
A =[0] + list(map(int,input().split()))+[N] # 递增
r = N//(n+1)
Long = 0
sum = 0

def g(x):
    return x//r

for i in range(1,n+2):
    sum1 = 0
    j = A[i-1]
    while j<A[i]:
        gx = g(j)
        numEnd = (gx+1)*r-1
        if numEnd>A[i]-1:   # f和g有交叉
            numEnd = A[i]-1
        numLong = numEnd-j+1
        f_g = abs(i-1-gx)
        sum1 += f_g*numLong
        Long = numLong
        j+=Long
    sum+=sum1

print(sum)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值