2026-07-13统计好子数组。用go语言给定一个整数数组 nums。对任意一个连续非空的子数组考察它里面所有元素的按位或值把该子数组中每个元素依次做按位或最终得到一个结果。如果这个按位或结果在该子数组中“至少出现过一次”也就是子数组里存在某个元素的值等于这个按位或结果那么称这个子数组为“好子数组”。请统计 nums 中所有好子数组的数量并返回这个总数。1 nums.length 100000。0 nums[i] 1000000000。输入 nums [4,2,3]。输出 4。解释nums 的子数组有子数组按位或结果存在于子数组中[4]4 4是[2]2 2是[3]3 3是[4, 2]4 | 2 6否[2, 3]2 | 3 3是[4, 2, 3]4 | 2 | 3 7否因此nums 的好子数组是 [4]、[2]、[3] 和 [2, 3]。所以答案为 4。题目来自力扣3878。大体步骤如下Go完整代码如下packagemainimport(fmt)funccountGoodSubarrays(nums[]int)(ansint64){n:len(nums)left:make([]int,n)st:[]int{-1}// 哨兵fori,x:rangenums{forlen(st)1nums[st[len(st)-1]]|xx{stst[:len(st)-1]}left[i]st[len(st)-1]// nums[left[i]] 不是 x 的子集stappend(st,i)}st[]int{n}fori:n-1;i0;i--{x:nums[i]// 比如 nums [...,1,...,1,...]我们规定包含左边的 1 的子数组不能包含右边的 1从而避免重复统计子数组// 注包含右边的 1 的子数组可以包含左边的 1forlen(st)1nums[st[len(st)-1]]!xnums[st[len(st)-1]]|xx{stst[:len(st)-1]}right:st[len(st)-1]// nums[right] 不是 x 的子集stappend(st,i)// 子数组左端点可以从 left[i]1 到 i一共 i-left[i] 个// 子数组右端点可以从 i 到 right-1一共 right-i 个ansint64(i-left[i])*int64(right-i)}return}funcmain(){nums:[]int{4,2,3}result:countGoodSubarrays(nums)fmt.Println(result)}Python完整代码如下# -*-coding:utf-8-*-defcountGoodSubarrays(nums):nlen(nums)left[0]*n st[-1]# 哨兵fori,xinenumerate(nums):whilelen(st)1and(nums[st[-1]]|x)x:st.pop()left[i]st[-1]# nums[left[i]] 不是 x 的子集st.append(i)ans0st[n]foriinrange(n-1,-1,-1):xnums[i]whilelen(st)1andnums[st[-1]]!xand(nums[st[-1]]|x)x:st.pop()rightst[-1]# nums[right] 不是 x 的子集st.append(i)ans(i-left[i])*(right-i)returnansif__name____main__:nums[4,2,3]resultcountGoodSubarrays(nums)print(result)C完整代码如下#includevector#includeiostreamusingnamespacestd;longlongcountGoodSubarrays(vectorintnums){intnnums.size();vectorintleft(n);vectorintst;st.push_back(-1);// 哨兵for(inti0;in;i){intxnums[i];while(st.size()1(nums[st.back()]|x)x){st.pop_back();}left[i]st.back();// nums[left[i]] 不是 x 的子集st.push_back(i);}longlongans0;st.clear();st.push_back(n);for(intin-1;i0;--i){intxnums[i];// 比如 nums [...,1,...,1,...]我们规定包含左边的 1 的子数组不能包含右边的 1从而避免重复统计子数组// 注包含右边的 1 的子数组可以包含左边的 1while(st.size()1nums[st.back()]!x(nums[st.back()]|x)x){st.pop_back();}intrightst.back();// nums[right] 不是 x 的子集st.push_back(i);// 子数组左端点可以从 left[i]1 到 i一共 i-left[i] 个// 子数组右端点可以从 i 到 right-1一共 right-i 个ans(longlong)(i-left[i])*(right-i);}returnans;}intmain(){vectorintnums{4,2,3};longlongresultcountGoodSubarrays(nums);coutresultendl;return0;}