You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
3.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package class_2022_03_3_week;
import java.util.Arrays;
// 来自美团
// void add(int L, int R, int C)代表在arr[L...R]上每个数加C
// int get(int L, int R)代表查询arr[L...R]上的累加和
// 假设你可以在所有操作开始之前重新排列arr
// 请返回每一次get查询的结果都加在一起最大能是多少
// 输入参数:
// int[] arr : 原始数组
// int[][] ops二维数组每一行解释如下:
// [a,b,c]如果数组有3个数表示调用add(a,b,c)
// [a,b]如果数组有2个数表示调用get(a,b)
// a和b表示arr范围范围假设从1开始不从0开始
// 输出:
// 假设你可以在开始时重新排列arr返回所有get操作返回值累计和最大是多少
public class Code04_ArrangeAddGetMax {
public static int maxGets(int[] arr, int[][] ops) {
int n = arr.length;
SegmentTree getTree = new SegmentTree(n);
for (int[] op : ops) {
if (op.length == 2) {
getTree.add(op[0], op[1], 1);
}
}
int[][] getCnts = new int[n][2];
for (int i = 1, j = 0; i <= n; i++, j++) {
getCnts[j][0] = j;
getCnts[j][1] = getTree.get(i, i);
}
Arrays.sort(getCnts, (a, b) -> a[1] - b[1]);
Arrays.sort(arr);
int[] reArrange = new int[n];
for (int i = 0; i < n; i++) {
reArrange[getCnts[i][0]] = arr[i];
}
SegmentTree st = new SegmentTree(reArrange);
int ans = 0;
for (int[] op : ops) {
if (op.length == 3) {
st.add(op[0], op[1], op[2]);
} else {
ans += st.get(op[0], op[1]);
}
}
return ans;
}
public static class SegmentTree {
private int n;
private int[] arr;
private int[] sum;
private int[] lazy;
public SegmentTree(int size) {
n = size + 1;
sum = new int[n << 2];
lazy = new int[n << 2];
n--;
}
public SegmentTree(int[] origin) {
n = origin.length + 1;
arr = new int[n];
for (int i = 1; i < n; i++) {
arr[i] = origin[i - 1];
}
sum = new int[n << 2];
lazy = new int[n << 2];
build(1, --n, 1);
}
private void build(int l, int r, int rt) {
if (l == r) {
sum[rt] = arr[l];
return;
}
int mid = (l + r) >> 1;
build(l, mid, rt << 1);
build(mid + 1, r, rt << 1 | 1);
pushUp(rt);
}
private void pushUp(int rt) {
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
private void pushDown(int rt, int ln, int rn) {
if (lazy[rt] != 0) {
lazy[rt << 1] += lazy[rt];
sum[rt << 1] += lazy[rt] * ln;
lazy[rt << 1 | 1] += lazy[rt];
sum[rt << 1 | 1] += lazy[rt] * rn;
lazy[rt] = 0;
}
}
public void add(int L, int R, int C) {
add(L, R, C, 1, n, 1);
}
private void add(int L, int R, int C, int l, int r, int rt) {
if (L <= l && r <= R) {
sum[rt] += C * (r - l + 1);
lazy[rt] += C;
return;
}
int mid = (l + r) >> 1;
pushDown(rt, mid - l + 1, r - mid);
if (L <= mid) {
add(L, R, C, l, mid, rt << 1);
}
if (R > mid) {
add(L, R, C, mid + 1, r, rt << 1 | 1);
}
pushUp(rt);
}
public int get(int L, int R) {
return query(L, R, 1, n, 1);
}
private int query(int L, int R, int l, int r, int rt) {
if (L <= l && r <= R) {
return sum[rt];
}
int mid = (l + r) >> 1;
pushDown(rt, mid - l + 1, r - mid);
int ans = 0;
if (L <= mid) {
ans += query(L, R, l, mid, rt << 1);
}
if (R > mid) {
ans += query(L, R, mid + 1, r, rt << 1 | 1);
}
return ans;
}
}
public static void main(String[] args) {
int[] arr = { 1, 2, 3, 4, 5 };
int[][] ops = { { 1, 3 }, { 2, 4 }, { 1, 5 } };
System.out.println(maxGets(arr, ops));
}
}