Woodyiiiiiii / LeetCode

My private record of Leetcode solution

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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());
        }

    }

}