2031. 1 比 0 多的子数组个数
作者:互联网
给你一个只包含 0 和 1 的数组 nums,请返回 1 的数量 大于 0 的数量的子数组的个数。由于答案可能很大,请返回答案对 109 + 7 取余 的结果。
一个 子数组 指的是原数组中连续的一个子序列。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/count-subarrays-with-more-ones-than-zeros
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
线段树
class Solution {
private static final int MOD = 1000000007;
private static final int BASE = 100000;
public int subarraysWithMoreZerosThanOnes(int[] nums) {
if (nums == null || nums.length == 0) {
return 0;
}
int n = 2 * BASE + 1;
Trie trie = new Trie(n);
trie.add(BASE + 1, BASE + 1, 1, 1, n, 1);
int sum = 0;
int ans = 0;
for (int num : nums) {
sum += (num == 0 ? -1 : num);
int m = trie.query(1, sum + BASE, 1, n, 1);
trie.add(sum + BASE + 1, sum + BASE + 1, 1, 1, n, 1);
ans = (ans + m) % MOD;
}
return ans;
}
}
class Trie {
private int[] sum;
private int[] add;
public Trie(int n) {
sum = new int[n << 2 | 1];
add = new int[n << 2 | 1];
}
private int left(int x) {
return x << 1;
}
private int right(int x) {
return x << 1 | 1;
}
private void pushDown(int ln, int rn, int rt) {
if (add[rt] != 0) {
add[left(rt)] += add[rt];
sum[left(rt)] += ln * add[rt];
add[right(rt)] += add[rt];
sum[right(rt)] += add[rt];
add[rt] = 0;
}
}
private void pushUp(int rt) {
sum[rt] = sum[left(rt)] + sum[right(rt)];
}
public void add(int L, int R, int val, int l, int r, int rt) {
if (L <= l && R >= r) {
sum[rt] += (r - l + 1) * val;
add[rt] += rt;
return;
}
int mid = (l + r) >> 1;
pushDown(mid - l + 1, r - mid, rt);
if (L <= mid) {
add(L, R, val, l, mid, rt << 1);
}
if (mid < R) {
add(L, R, val, mid + 1, r, rt << 1 | 1);
}
pushUp(rt);
}
public int query(int L, int R, int l, int r, int rt) {
if (L > R) {
return 0;
}
if (L <= l && R >= r) {
return sum[rt];
}
int mid = (l + r) >> 1;
pushDown(mid - l + 1, r - mid, rt);
int ans = 0;
if (L <= mid) {
ans += query(L, R, l, mid, rt << 1);
}
if (mid < R) {
ans += query(L, R, mid + 1, r, rt << 1 | 1);
}
return ans;
}
}
线性扫描
标签:rt,return,2031,int,sum,个数,mid,BASE,数组 来源: https://www.cnblogs.com/tianyiya/p/16068475.html