Codeforces Round 881 (Div.3) F1. Omsk Metro (simple version)
Woodyiiiiiii opened this issue · comments
F1. Omsk Metro (simple version)
F1. Omsk Metro (simple version)
这道题先从时间复杂度出发,可以发现只能在O(n)条件下解决了,也就是说,在加节点的过程中O(1)算法计算某些需要的数值。
我第一想法就是记录最值。题目求的是从根节点到当前节点的子路径的权值之和是否有k。再观察题目,权值很有意思地设置成了{-1,1},说明路径和是有序变化的。再把路径看成数组,那么要求是否有k,我们只要知道k是否在当前范围内最大/最小子数组权值之和即可。
那如何求子数组权值最值呢?也就是DP/Kadane算法。同时用max/min数组代表之前的最值。
类似题目:
53. Maximum Subarray
import java.io.*;
import java.util.*;
/**
* codeforces template
*/
public class Main {
static final Reader RR = new Reader(System.in);
static final PrintWriter PP = new PrintWriter(System.out, true);
static final int MAX_BIT = 31;
static final int MAX = 200001;
public static void main(String[] args) throws IOException {
int T = RR.nextInt();
int[] vals = new int[MAX];
int[] max = new int[MAX], min = new int[MAX];
int[] s1 = new int[MAX], s2 = new int[MAX];
s1[1] = s2[1] = 1;
max[1] = 1;
min[1] = 0;
while (T -- > 0) {
Map<Integer, Set<Integer>> g = new HashMap<>();
vals[1] = 1;
int n = RR.nextInt();
int b = 1;
while (n-- > 0) {
char op = RR.next().charAt(0);
if (op == '+') {
b++;
int u = RR.nextInt(), x = RR.nextInt();
g.putIfAbsent(u, new HashSet<>());
g.get(u).add(b);
vals[b] = x;
// kadane's algorithm
s1[b] = Math.max(s1[u] + x, x);
s2[b] = Math.min(s2[u] + x, x);
max[b] = Math.max(max[u], s1[b]);
min[b] = Math.min(min[u], s2[b]);
} else if (op == '?') {
int u = RR.nextInt(), v = RR.nextInt(), k = RR.nextInt();
if (k == 0) {
PP.println("YES");
continue;
}
if (k >= min[v] && k <= max[v]) {
PP.println("YES");
} else {
PP.println("NO");
}
}
}
}
}
static class Reader {
private final BufferedReader reader;
private StringTokenizer tokenizer;
public Reader(InputStream inputStream) {
this.reader = new BufferedReader(new InputStreamReader(inputStream), 65536);
this.tokenizer = new StringTokenizer("");
}
public String next() throws IOException {
while (!tokenizer.hasMoreTokens()) {
tokenizer = new StringTokenizer(reader.readLine());
}
return tokenizer.nextToken();
}
public int nextInt() throws IOException {
return Integer.parseInt(next());
}
public long nextLong() throws IOException {
return Long.parseLong(next());
}
}
}