Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Codeforces Round 881 (Div.3) F1. Omsk Metro (simple version) #276

Open
Woodyiiiiiii opened this issue Jul 7, 2023 · 0 comments
Open

Codeforces Round 881 (Div.3) F1. Omsk Metro (simple version) #276

Woodyiiiiiii opened this issue Jul 7, 2023 · 0 comments

Comments

@Woodyiiiiiii
Copy link
Owner

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

    }

}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant