A dual-core processor has one process queue per core. There are n processes; time[i] is the processing time of the i-th. There is a latch that decides which core picks. Initially the latch is with core 1. When the latch is held by core c and process i needs to be assigned, one of the two operations must be performed:
- Assign process
ito corec; pass the latch to the other core. - Assign process
ito the other core; the latch stays with corec.
Each core, when it holds the latch, picks the operation that maximizes its own total accumulated time. Return [total_core1, total_core2] under optimal play.
Example
n = 5
time = [10, 21, 10, 21, 10]
Output: [41, 31]
Constraints
- 1 ≤ n ≤ 10⁵
- 1 ≤ time[i] ≤ 10⁹
解法
在 (i, latch) 上做博弈 DP。f(i, c) 表示从下标 i 开始、latch 在 core c 手里、两方均最优时核 1 与核 2 的最终得分对 (a, b)。当前持有 latch 的核 c 在两个转移中选使自己 (a, b)[c-1] 最大的那个。从 i = n(终态 (0, 0))自底向上递推。时间和空间均 O(n)。
def get_process_time(time):
n = len(time)
# f[i][c] = (a, b) when start at i, latch = c (c in {1, 2})
f = [[(0, 0), (0, 0)] for _ in range(n + 1)]
for i in range(n - 1, -1, -1):
for c in (1, 2):
# Option A: assign to core c, latch flips
a1, b1 = f[i + 1][3 - c - 1] if False else f[i + 1][(3 - c) - 1]
optA = (a1 + (time[i] if c == 1 else 0),
b1 + (time[i] if c == 2 else 0))
# Option B: assign to the other core, latch stays
a2, b2 = f[i + 1][c - 1]
other = 3 - c
optB = (a2 + (time[i] if other == 1 else 0),
b2 + (time[i] if other == 2 else 0))
f[i][c - 1] = optA if optA[c - 1] >= optB[c - 1] else optB
return list(f[0][0]) # latch starts at core 1class Solution {
static long[] getProcessTime(int[] time) {
int n = time.length;
long[][][] f = new long[n + 1][2][2]; // f[i][c-1] = {a, b}
for (int i = n - 1; i >= 0; i--) {
for (int c = 1; c <= 2; c++) {
int other = 3 - c;
long[] na = f[i + 1][other - 1]; // latch flips to other
long[] optA = { na[0] + (c == 1 ? time[i] : 0),
na[1] + (c == 2 ? time[i] : 0) };
long[] nb = f[i + 1][c - 1]; // latch stays at c
long[] optB = { nb[0] + (other == 1 ? time[i] : 0),
nb[1] + (other == 2 ? time[i] : 0) };
if (optA[c - 1] >= optB[c - 1]) f[i][c - 1] = optA;
else f[i][c - 1] = optB;
}
}
return f[0][0];
}
}vector<long long> getProcessTime(vector<int>& time) {
int n = time.size();
vector<vector<array<long long, 2>>> f(n + 1, vector<array<long long, 2>>(2, {0, 0}));
for (int i = n - 1; i >= 0; i--) {
for (int c = 1; c <= 2; c++) {
int other = 3 - c;
auto& na = f[i + 1][other - 1];
array<long long, 2> optA = { na[0] + (c == 1 ? (long long)time[i] : 0),
na[1] + (c == 2 ? (long long)time[i] : 0) };
auto& nb = f[i + 1][c - 1];
array<long long, 2> optB = { nb[0] + (other == 1 ? (long long)time[i] : 0),
nb[1] + (other == 2 ? (long long)time[i] : 0) };
f[i][c - 1] = optA[c - 1] >= optB[c - 1] ? optA : optB;
}
}
return { f[0][0][0], f[0][0][1] };
}A network of warehouses is an undirected rooted weighted tree with warehouse_nodes nodes rooted at warehouse 1. Each node has a value val[v]. A pair (u, v) is compatible iff:
uis an ancestor ofvin the tree.distance(u, v) ≤ val[v].
Count compatible pairs.
Example: with the input from the OA, the answer is 5.
Constraints
- 1 ≤ warehouse_nodes ≤ 1.5·10⁵
- 1 ≤ warehouse_weight[i] ≤ 10⁴
- 1 ≤ val[i] ≤ 10⁹
解法
记 D[v] 为根到 v 的带权距离。条件 distance(u, v) = D[v] - D[u] ≤ val[v] 等价于 D[u] ≥ D[v] - val[v]。迭代 DFS,维护当前路径上所有祖先的 D[u] 有序多重集。到达 v 时二分统计满足 D[u] ≥ D[v] - val[v] 的祖先数累入答案;入栈时插入 D[v],出栈时删除。时间 O(n log n),空间 O(n)。n = 1.5·10⁵ 时用迭代避免递归爆栈。
from sortedcontainers import SortedList
def count_compatible_pairs(warehouse_nodes, frm, to, weight, val):
n = warehouse_nodes
g = [[] for _ in range(n + 1)]
for a, b, w in zip(frm, to, weight):
g[a].append((b, w))
g[b].append((a, w))
ans = 0
sl = SortedList()
# iterative DFS
stack = [(1, 0, 0, iter(g[1]), 'enter')]
D = [0] * (n + 1)
visited = [False] * (n + 1)
visited[1] = True
sl.add(0)
parent = {1: 0}
order = [1]
it_stack = [iter(g[1])]
node_stack = [1]
while node_stack:
u = node_stack[-1]
it = it_stack[-1]
advanced = False
for nb, w in it:
if not visited[nb]:
visited[nb] = True
D[nb] = D[u] + w
# count compatible ancestors of nb
threshold = D[nb] - val[nb - 1]
idx = sl.bisect_left(threshold)
ans += len(sl) - idx
sl.add(D[nb])
node_stack.append(nb)
it_stack.append(iter(g[nb]))
advanced = True
break
if not advanced:
sl.remove(D[u])
node_stack.pop()
it_stack.pop()
return ansclass Solution {
static long countCompatiblePairs(int warehouseNodes, int[] from, int[] to, int[] weight, int[] val) {
int n = warehouseNodes;
List<int[]>[] g = new List[n + 1];
for (int i = 1; i <= n; i++) g[i] = new ArrayList<>();
for (int i = 0; i < from.length; i++) {
g[from[i]].add(new int[]{to[i], weight[i]});
g[to[i]].add(new int[]{from[i], weight[i]});
}
long[] D = new long[n + 1];
TreeMap<Long, Integer> ms = new TreeMap<>();
ms.merge(0L, 1, Integer::sum);
long ans = 0;
int[] parent = new int[n + 1];
int[] iter = new int[n + 1];
Deque<Integer> stack = new ArrayDeque<>();
stack.push(1);
parent[1] = 0;
while (!stack.isEmpty()) {
int u = stack.peek();
boolean advanced = false;
while (iter[u] < g[u].size()) {
int[] e = g[u].get(iter[u]++);
int nb = e[0], w = e[1];
if (nb == parent[u]) continue;
parent[nb] = u;
D[nb] = D[u] + w;
long threshold = D[nb] - val[nb - 1];
int count = 0;
for (var entry : ms.tailMap(threshold).entrySet()) count += entry.getValue();
ans += count;
ms.merge(D[nb], 1, Integer::sum);
stack.push(nb);
advanced = true;
break;
}
if (!advanced) {
ms.merge(D[u], -1, Integer::sum);
if (ms.get(D[u]) == 0) ms.remove(D[u]);
stack.pop();
}
}
return ans;
}
}long long countCompatiblePairs(int warehouseNodes, vector<int>& from, vector<int>& to,
vector<int>& weight, vector<int>& val) {
int n = warehouseNodes;
vector<vector<pair<int,int>>> g(n + 1);
for (size_t i = 0; i < from.size(); i++) {
g[from[i]].push_back({to[i], weight[i]});
g[to[i]].push_back({from[i], weight[i]});
}
vector<long long> D(n + 1, 0);
multiset<long long> ms;
ms.insert(0);
long long ans = 0;
vector<int> parent(n + 1, 0), it(n + 1, 0);
vector<int> stack;
stack.push_back(1);
while (!stack.empty()) {
int u = stack.back();
bool advanced = false;
while (it[u] < (int)g[u].size()) {
auto [nb, w] = g[u][it[u]++];
if (nb == parent[u]) continue;
parent[nb] = u;
D[nb] = D[u] + w;
long long threshold = D[nb] - val[nb - 1];
ans += distance(ms.lower_bound(threshold), ms.end());
ms.insert(D[nb]);
stack.push_back(nb);
advanced = true;
break;
}
if (!advanced) {
ms.erase(ms.find(D[u]));
stack.pop_back();
}
}
return ans;
}> Note: the Java/C++ implementations use TreeMap / multiset which give O(log n) insertion and removal but O(n) worst-case tail-count via iteration; for the full constraint use a Fenwick tree over compressed D values.
Given array arr of n integers, the operation is: choose index i (0 ≤ i < n - 1) and swap arr[i] and arr[i + 1]. Each element can participate in at most one swap. Strength of index i is arr[i] * (i + 1) (0-indexed). Maximize the sum Σ arr[i] * (i + 1).
Example
n = 5
arr = [1, 9, 7, 3, 2]
Output: 66 // swap (arr[2], arr[3]) -> [1, 9, 3, 7, 2]
Constraints
- 1 ≤ n ≤ 10⁵
- 1 ≤ arr[i] ≤ 10⁵
解法
每个元素至多参与一次交换,所以两次相邻交换不能共享元素,选中的交换位置构成不相交的相邻对。DP:dp[i] 表示长度为 i 前缀的最大力量和。
dp[0] = 0
dp[1] = arr[0] * 1
dp[i] = max(dp[i-1] + arr[i-1] * i,
dp[i-2] + arr[i-1] * (i-1) + arr[i-2] * i) // 交换位置 i-1, i-2
答案为 dp[n]。复杂度 O(n)。
def get_maximum_sum_of_strengths(arr):
n = len(arr)
if n == 0:
return 0
dp = [0] * (n + 1)
dp[1] = arr[0] * 1
for i in range(2, n + 1):
keep = dp[i - 1] + arr[i - 1] * i
swap = dp[i - 2] + arr[i - 1] * (i - 1) + arr[i - 2] * i
dp[i] = max(keep, swap)
return dp[n]class Solution {
static long getMaximumSumOfStrengths(int[] arr) {
int n = arr.length;
if (n == 0) return 0;
long[] dp = new long[n + 1];
dp[1] = (long) arr[0] * 1;
for (int i = 2; i <= n; i++) {
long keep = dp[i - 1] + (long) arr[i - 1] * i;
long swap = dp[i - 2] + (long) arr[i - 1] * (i - 1) + (long) arr[i - 2] * i;
dp[i] = Math.max(keep, swap);
}
return dp[n];
}
}long long getMaximumSumOfStrengths(vector<int>& arr) {
int n = arr.size();
if (n == 0) return 0;
vector<long long> dp(n + 1, 0);
dp[1] = (long long) arr[0] * 1;
for (int i = 2; i <= n; i++) {
long long keep = dp[i - 1] + (long long) arr[i - 1] * i;
long long swap = dp[i - 2] + (long long) arr[i - 1] * (i - 1) + (long long) arr[i - 2] * i;
dp[i] = max(keep, swap);
}
return dp[n];
}