1 条题解

  • 0
    @ 2025-5-26 8:41:32

    题解:区间最大频率查询

    这道题要求在非递减序列中查询区间内出现次数最多的数值的频率。由于序列非递减,相同数值会连续出现,因此可以预处理每个位置的连续出现次数,并使用RMQ(Range Maximum Query)算法高效查询区间最大值。

    解决代码

    import sys
    import math
    
    def main():
        input = sys.stdin.read().split()
        ptr = 0
        while True:
            n = int(input[ptr])
            ptr += 1
            if n == 0:
                break
            q = int(input[ptr])
            ptr += 1
            arr = list(map(int, input[ptr:ptr+n]))
            ptr += n
            
            # 预处理每个位置的连续出现次数
            s = [1] * n
            for i in range(1, n):
                if arr[i] == arr[i-1]:
                    s[i] = s[i-1] + 1
                else:
                    s[i] = 1
            
            # 预处理RMQ表
            logn = math.floor(math.log2(n)) if n > 0 else 0
            rmq = [[0] * (logn + 1) for _ in range(n)]
            for i in range(n):
                rmq[i][0] = s[i]
            for k in range(1, logn + 1):
                for i in range(n - (1 << k) + 1):
                    rmq[i][k] = max(rmq[i][k-1], rmq[i + (1 << (k-1))][k-1])
            
            # 处理查询
            for _ in range(q):
                l = int(input[ptr]) - 1  # 转换为0-based
                ptr += 1
                r = int(input[ptr]) - 1
                ptr += 1
                
                # 找到左端点所在连续段的末尾
                cnt = l
                while cnt < r and arr[cnt] == arr[cnt + 1]:
                    cnt += 1
                
                # 计算左端点所在段的贡献
                left_count = cnt - l + 1
                
                # 剩余区间的最大值
                remaining_max = 0
                if cnt + 1 <= r:
                    a = cnt + 1
                    b = r
                    length = b - a + 1
                    k = 0
                    while (1 << (k + 1)) <= length:
                        k += 1
                    remaining_max = max(rmq[a][k], rmq[b - (1 << k) + 1][k])
                
                print(max(left_count, remaining_max))
    
    if __name__ == "__main__":
        main()
    

    这种方法通过预处理将查询复杂度优化到O(1),适用于大规模数据的高效查询。

    • 1

    信息

    ID
    2369
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者