算法 BISHI66 子数列求积 思路 求解代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 private static final int MOD = 1000000007; /** * 主函数,处理输入输出并计算区间乘积 * * @param args 命令行参数 * @throws IOException 可能抛出IO异常 */ public static void main(String[] args) throws IOException { // 使用BufferedReader读取输入,PrintWriter输出结果 BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); // 读取第一行输入,分割字符串并解析为整数n和q String[] str = br.readLine().trim().split("\\s+"); int n = Integer.parseInt(str[0]); // 数组长度 int q = Integer.parseInt(str[1]); // 查询次数 // 创建前缀积数组,大小为n+1 long[] preProduct = new long[n + 1]; preProduct[0] = 1; // 初始化前缀积的第一个元素为1 // 读取数组元素并计算前缀积 String[] numStr = br.readLine().trim().split("\\s+"); for (int i = 1; i <= n; i++) { long val = Long.parseLong(numStr[i - 1]); // 解析当前元素 // 计算前缀积,并对MOD取模 preProduct[i] = (preProduct[i - 1] * val) % MOD; } // 创建结果列表 List<Long> res = new ArrayList<>(); // 处理每个查询 for (int i = 0; i < q; i++) { // 读取查询区间 String[] strQ = br.readLine().split("\\s+"); int l = Integer.parseInt(strQ[0]); // 区间左端点 int r = Integer.parseInt(strQ[1]); // 区间右端点 // 计算preProduct[l-1]的模逆元 long invPreProduct = mypower(preProduct[l - 1], MOD - 2, MOD); // 计算区间[l,r]的乘积 long ans = (preProduct[r] * invPreProduct) % MOD; res.add(ans); // 将结果添加到列表中 } // 使用StringBuilder构建输出字符串 StringBuilder sb = new StringBuilder(); for (int i = 0; i < res.size(); i++) { // 每个结果用空格分隔,最后一个结果后不加空格 sb.append(res.get(i)).append(res.size() == n - 1 ? "" : " "); } // 输出结果并关闭流 out.println(sb.toString()); out.flush(); out.close(); br.close(); } private static long mypower(long base, long exp, long mod) { long ans = 1 % mod; while (exp > 0) { if (exp % 2 == 1) { ans = (ans * base) % mod; } base = (base * base) % mod; exp /= 2; } return ans; }