当前位置: 首页 > news >正文

Kimi LeetCode 3145. 大数组元素的乘积 Java实现

我来搜索一下 LeetCode 3145 这道题的详细信息
根据搜索结果,我来为你提供 LeetCode 3145「大数组元素的乘积」的 Java 实现。

题目理解

- 强数组:一个非负整数 `x` 的强数组是由 `x` 的二进制表示中所有为1的位对应的2的幂组成的有序数组。例如 `10 = 1010₂`,强数组为 `[2, 8]`。
- big_nums:将每个正整数的强数组拼接起来:`[1, 2, 1, 2, 4, 1, 4, 2, 4, 1, 2, 4, 8, ...]`
- 查询 `queries[i] = [from, to, mod]`,求 `big_nums[from..to]` 的乘积对 `mod` 取模

关键洞察:big_nums 中每个元素都是 2 的幂,所以乘积也是 2 的幂。设幂次之和为 `power`,答案就是 `2^power % mod`。因此问题转化为求区间内所有元素的幂次之和。

Java 实现(试填法 + 快速幂)

```java
class Solution {

// 快速幂:计算 a^b % mod
private long qpow(long a, long b, long mod) {
long res = 1 % mod;
a %= mod;
while (b > 0) {
if ((b & 1) == 1) {
res = res * a % mod;
}
a = a * a % mod;
b >>= 1;
}
return res;
}

/**
* 计算 big_nums 前 k 个元素的幂次之和
* 即:big_nums[0] 到 big_nums[k-1] 中所有 2 的幂的指数之和
*
* 核心思想(试填法):
* 对于数字 n,其二进制表示中1的个数为 popcount(n)
* 前 n 个正整数的强数组总长度 = 所有 popcount(1..n) 之和
*
* 我们维护:
* - n: 当前已确定的数字(二进制形式)
* - cnt1: n 中已填的1的个数
* - sum_i: n 中已填的1的位下标之和
*
* 从高位到低位试填,如果填1后新增的幂次个数不超过k,就填1
*/
private long calc(long k) {
long res = 0; // 幂次之和
long n = 0; // 当前确定的数字
long cnt1 = 0; // 已填的1的个数
long sum_i = 0; // 已填的1的位下标之和

// 从高位到低位试填(最低位 i=0 单独处理)
// __lg(k + 1) 找到最高可能的位数
for (long i = 63 - Long.numberOfLeadingZeros(k + 1); i > 0; i--) {
// 如果在第 i 位填1,新增的幂次个数:
// 1. 之前已填的 cnt1 个1,每个都会在新分支中重复 2^i 次 -> cnt1 * 2^i
// 2. 新填的1在第 i 位,会在 [0, 2^i) 的每个数字中出现一次 -> i * 2^(i-1)
long c = (cnt1 << i) + (i << (i - 1));

if (c <= k) {
k -= c;
// 新增幂次之和:
// 1. 之前已填的 sum_i 个幂次,每个重复 2^i 次 -> sum_i * 2^i
// 2. 新填的第 i 位,在 [0, 2^i) 中每个数字贡献 i -> i * (i-1)/2 * 2^(i-1)
res += (sum_i << i) + ((i * (i - 1) / 2) << (i - 1));
sum_i += i;
cnt1++;
n |= 1L << i; // 在第 i 位填1
}
}

// 最低位(i = 0)单独处理
if (cnt1 <= k) {
k -= cnt1;
res += sum_i; // 最低位填1,每个已有1贡献0次幂(因为2^0=1,指数为0)
n |= 1; // 最低位填1
}

// 剩余的 k 个幂次,由 n 的低 k 个1的位下标补充
while (k-- > 0) {
// n & -n 得到最低位的1
long lowbit = n & -n;
// 该1的位下标
res += Long.numberOfTrailingZeros(lowbit);
// 去掉最低位的1
n &= n - 1;
}

return res;
}

public int[] findProductsOfElements(long[][] queries) {
int m = queries.length;
int[] ans = new int[m];

for (int i = 0; i < m; i++) {
long from = queries[i][0];
long to = queries[i][1];
long mod = queries[i][2];

// 前 to+1 个元素的幂次和 - 前 from 个元素的幂次和 = [from, to] 区间的幂次和
long power = calc(to + 1) - calc(from);

ans[i] = (int) qpow(2, power, mod);
}

return ans;
}
}
```

核心思路图解

```
数字 n 的强数组 = n 的二进制中所有1对应的 2^i

big_nums: [1] [2] [1,2] [4] [1,4] [2,4] [1,2,4] [8] ...
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
幂次数组: [0] [1] [0,1] [2] [0,2] [1,2] [0,1,2] [3] ...

问题转化为:求幂次数组区间和,然后 2^和 % mod

calc(k): 求 big_nums 前 k 个元素的幂次之和
= 所有数字 1..n 的二进制中1的位下标之和(前k个)
```

复杂度分析

指标 复杂度
时间 O(q \cdot \log U),其中 q 是查询数,U \approx 10^{15}
空间 O(1)

试填法从高位到低位逐位确定,每位 O(1),最多 50 位(因为 2^{50} > 10^{15}),所以单次 `calc` 约 O(\log U)。

http://www.zskr.cn/news/1502888.html

相关文章:

  • 2026贵阳黄金回收全攻略 三大靠谱门店详解及避坑指南 - 润富黄金回收
  • 2026年武汉光谷科技职业技术学校招生简章深度解析:专业设置与办学特色盘点 - GrowthUME
  • 告别黑盒:用CANoe和Python脚本实战解析UDS 0x19服务的DTC数据流
  • 嵌入式系统内存保护与外部总线接口:MPU与EBI原理、配置与实战
  • 7个免费Flutter UI套件完整实战指南:从零构建专业级移动应用界面
  • 口述编程实战:1天做出一个能赚钱的在线工具(vibe-coding产品实操)
  • 2026 烟台厨卫屋面地下室漏水瓷砖空鼓测评:吉修匠 99.8 分五星榜首 - 吉修匠
  • oracle CDB用户管理
  • Windows内核:微软帝国的基石
  • 基于51单片机的病床呼叫系统(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_可以扫码或者私信
  • 淮安黄金回收全攻略 靠谱商家与避坑指南 - 润富黄金回收
  • BootstrapVue Next终极指南:如何在Vue 3项目中快速构建现代化UI界面
  • 2026郑州黄金回收基础知识科普:不同品类黄金区分与计价逻辑 - 禹竞
  • 数据的加密与解密(08:31)
  • 用C语言手搓一个RSA加密工具:从生成密钥到加解密的完整流程(附完整代码)
  • Scrapling终极指南:3步快速掌握Python网络爬虫框架
  • 钢筋网片厂家技术解析:双边丝护栏网/成都护栏网厂家/成都钢筋网片厂家/护栏网专业生产厂家/品质与供货能力核心对比 - 优质品牌商家
  • 25元PS2手柄变身高精度遥控器:基于STM32F4的机器人/小车控制实战
  • 别再只盯着IoU了!3D点云重建中,Chamfer Distance (CD) 的保姆级PyTorch实现与避坑指南
  • 2026年深圳市黄金白银铂金彩金回收靠谱门店TOP5实力榜单无套路;实力店铺推荐及联系方式一览 - 亦辰小黄鸭
  • 保姆级教程:从Hook NewStringUTF开始,一步步逆向App登录的DES和MD5算法
  • 2026年十堰市黄金白银铂金彩金回收靠谱门店TOP5实力榜单无套路;实力店铺推荐及联系方式一览 - 亦辰小黄鸭
  • 数据的加密与解密(08:26)
  • 金价走高绍兴闲置黄金变现全攻略 - 润富黄金回收
  • 3分钟搭建全栈后端:InsForge让你的AI编码代理拥有完整后端能力
  • 2026年衢州市黄金白银铂金彩金回收靠谱门店TOP5实力榜单无套路;实力店铺推荐及联系方式一览 - 亦辰小黄鸭
  • 别再对着手册发愁了!手把手教你用FPGA驱动ADS1256实现24位高精度ADC采集(附Verilog代码避坑点)
  • 2026年石嘴山市黄金白银铂金彩金回收靠谱门店TOP5实力榜单无套路;实力店铺推荐及联系方式一览 - 亦辰小黄鸭
  • 2026年天津离婚律师推荐指南:从财产分割到子女抚养权全覆盖 - 本地品牌推荐
  • CrackMe实战:当验证逻辑藏在1ms定时器里,我是如何一步步写出注册机的