首页 > 试题广场 >

子数列求积

[编程题]子数列求积
  • 热度指数:2532 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
\hspace{15pt}给定一个长度为 n 的正整数序列 \{a_1,a_2,\dots ,a_n\} 。接下来有 q 次独立查询,第 j 次查询给出一对下标 l_j,r_j ,请你计算区间乘积


\prod\limits_{i=l_j}^{r_j} a_i


\hspace{15pt}并对模数 10^9+7 取模后的结果。

输入描述:
\hspace{15pt}第一行输入两个整数 n,q\left(1 \leqq n,q \leqq 10^5\right) ,分别表示序列长度与查询数量。
\hspace{15pt}第二行输入 n 个整数 a_1,a_2,\dots ,a_n\left(1 \leqq a_i < 10^9+7\right) ,表示序列元素。
\hspace{15pt}此后 q 行,第 j 行输入两个整数 l_j,r_j\left(1 \leqq l_j \leqq r_j \leqq n\right) ,表示一次查询的左右端点。


输出描述:
\hspace{15pt}输出一行 q 个用空格隔开的整数,第 j 个整数为第 j 次查询的答案。
示例1

输入

5 3
1 2 3 4 5
1 2
1 3
2 5

输出

2 6 120

说明

区间 [1,2] 的乘积为 1\times2=2[1,3] 的乘积为 1\times2\times3=6[2,5] 的乘积为 2\times3\times4\times5 = 120
前缀数组 + 乘法逆元
Python 写起来简单。
from functools import cache
from itertools import accumulate

MOD = int(1e9 + 7)

n, q = map(int, input().split())
arr = list(map(int, input().split()))
pre = list(accumulate(arr, lambda a, b: a * b % MOD))
pre.append(1)

@cache
def inverse(x):
    return pow(x, MOD - 2, MOD)

def divide(a, b):
    return a * inverse(b) % MOD 

ans = []
for _ in range(q):
    l, r = map(int, input().split())
    ans.append(divide(pre[r - 1], pre[l - 2]))

print(' '.join(str(x) for x in ans))


发表于 2026-01-13 16:26:26 回复(0)