結果
問題 | No.1030 だんしんぐぱーりない |
ユーザー | ks2m |
提出日時 | 2020-04-17 22:50:41 |
言語 | Java21 (openjdk 21) |
結果 |
TLE
(最新)
AC
(最初)
|
実行時間 | - |
コード長 | 5,501 bytes |
コンパイル時間 | 4,053 ms |
コンパイル使用メモリ | 91,524 KB |
実行使用メモリ | 97,348 KB |
最終ジャッジ日時 | 2024-04-14 15:07:32 |
合計ジャッジ時間 | 53,219 ms |
ジャッジサーバーID (参考情報) |
judge3 / judge4 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 61 ms
50,552 KB |
testcase_01 | AC | 59 ms
50,680 KB |
testcase_02 | AC | 60 ms
50,620 KB |
testcase_03 | AC | 60 ms
50,660 KB |
testcase_04 | AC | 61 ms
50,636 KB |
testcase_05 | AC | 1,723 ms
83,016 KB |
testcase_06 | AC | 1,389 ms
79,900 KB |
testcase_07 | AC | 1,167 ms
68,652 KB |
testcase_08 | AC | 1,092 ms
67,228 KB |
testcase_09 | AC | 1,281 ms
79,900 KB |
testcase_10 | AC | 800 ms
63,548 KB |
testcase_11 | AC | 1,703 ms
71,392 KB |
testcase_12 | AC | 1,301 ms
77,660 KB |
testcase_13 | AC | 1,194 ms
78,836 KB |
testcase_14 | AC | 1,436 ms
74,148 KB |
testcase_15 | AC | 1,004 ms
66,400 KB |
testcase_16 | AC | 1,297 ms
71,176 KB |
testcase_17 | AC | 1,409 ms
80,536 KB |
testcase_18 | AC | 1,685 ms
74,740 KB |
testcase_19 | AC | 1,092 ms
67,012 KB |
testcase_20 | AC | 1,174 ms
72,040 KB |
testcase_21 | AC | 1,356 ms
69,744 KB |
testcase_22 | AC | 1,149 ms
72,044 KB |
testcase_23 | AC | 1,416 ms
69,636 KB |
testcase_24 | AC | 1,230 ms
67,820 KB |
testcase_25 | AC | 1,346 ms
69,044 KB |
testcase_26 | AC | 954 ms
61,996 KB |
testcase_27 | AC | 1,065 ms
66,056 KB |
testcase_28 | AC | 1,387 ms
78,768 KB |
testcase_29 | AC | 1,129 ms
77,024 KB |
testcase_30 | AC | 1,057 ms
71,452 KB |
testcase_31 | AC | 1,185 ms
70,608 KB |
testcase_32 | AC | 1,404 ms
80,296 KB |
testcase_33 | AC | 1,366 ms
79,680 KB |
testcase_34 | AC | 830 ms
64,416 KB |
testcase_35 | AC | 1,956 ms
95,188 KB |
testcase_36 | AC | 1,921 ms
96,952 KB |
testcase_37 | TLE | - |
testcase_38 | TLE | - |
testcase_39 | AC | 1,889 ms
95,036 KB |
testcase_40 | AC | 71 ms
50,376 KB |
testcase_41 | AC | 59 ms
50,308 KB |
ソースコード
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.function.BiFunction; public class Main { static int[] c; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String[] sa = br.readLine().split(" "); int n = Integer.parseInt(sa[0]); int k = Integer.parseInt(sa[1]); int q = Integer.parseInt(sa[2]); sa = br.readLine().split(" "); c = new int[n]; for (int i = 0; i < n; i++) { c[i] = Integer.parseInt(sa[i]); } sa = br.readLine().split(" "); int[] a = new int[k]; for (int i = 0; i < k; i++) { a[i] = Integer.parseInt(sa[i]) - 1; } List<List<Integer>> list = new ArrayList<>(n); for (int i = 0; i < n; i++) { list.add(new ArrayList<>()); } for (int i = 0; i < n - 1; i++) { sa = br.readLine().split(" "); int e = Integer.parseInt(sa[0]) - 1; int f = Integer.parseInt(sa[1]) - 1; list.get(e).add(f); list.get(f).add(e); } SegTreeLCA lca = new SegTreeLCA(n, list, 0); SegTree<Integer> st = new SegTree<Integer>(k, -1, (o1, o2) -> { if (o1 == -1) return o2; if (o2 == -1) return o1; return lca.lca(o1, o2).i; }); for (int i = 0; i < k; i++) { st.update(i, a[i]); } PrintWriter pw = new PrintWriter(System.out); for (int i = 0; i < q; i++) { sa = br.readLine().split(" "); if (sa[0].equals("1")) { int x = Integer.parseInt(sa[1]) - 1; int y = Integer.parseInt(sa[2]) - 1; st.update(x, y); } else { int l = Integer.parseInt(sa[1]) - 1; int r = Integer.parseInt(sa[2]); pw.println(lca.get(st.query(l, r)).c); } } pw.flush(); br.close(); } static class SegTreeLCA { int n = 2; int n2, idx; Obj[] arr; int[] first; Obj INF = new Obj(-1, Integer.MAX_VALUE, 0); /** * 初期化 * @param size 頂点数 * @param list 隣接リスト * @param root 根の頂点番号 */ public SegTreeLCA(int size, List<List<Integer>> list, int root) { while (n < size) { n <<= 1; } n <<= 1; n2 = n * 2 - 1; idx = n - 1; arr = new Obj[n2]; first = new int[size]; Arrays.fill(first, -1); Obj r = new Obj(root, 0, c[root]); arr[idx] = r; first[root] = idx - n + 1; idx++; dfs(list, r, -1); for (int i = idx; i < n2; i++) { arr[i] = INF; } for (int i = n - 2; i >= 0; i--) { if (arr[i * 2 + 1].dep < arr[i * 2 + 2].dep) { arr[i] = arr[i * 2 + 1]; } else { arr[i] = arr[i * 2 + 2]; } } } private void dfs(List<List<Integer>> list, Obj cur, int p) { for (int ch : list.get(cur.i)) { if (ch != p) { int cmax = Math.max(cur.c, c[ch]); Obj o = new Obj(ch, cur.dep + 1, cmax); arr[idx] = o; if (first[ch] == -1) { first[ch] = idx - n + 1; } idx++; dfs(list, o, cur.i); arr[idx] = cur; idx++; } } } /** * 頂点Iのオブジェクト取得(0≦I<size) */ public Obj get(int i) { return arr[first[i] + n - 1]; } /** * 頂点A,BのLCA取得(0≦A,B<size) */ public Obj lca(int a, int b) { int l = Math.min(first[a], first[b]); int r = Math.max(first[a], first[b]); return query(l, r + 1, 0, 0, n); } private Obj query(int l, int r, int k, int beg, int end) { if (end <= l || r <= beg) return INF; // 交差しない if (l <= beg && end <= r) return arr[k]; // 完全に含む Obj o1 = query(l, r, k * 2 + 1, beg, (beg + end) / 2); Obj o2 = query(l, r, k * 2 + 2, (beg + end) / 2, end); if (o1.dep < o2.dep) { return o1; } return o2; } private static class Obj { int i, dep, c; public Obj(int i, int dep, int c) { this.i = i; this.dep = dep; this.c = c; } } } static class SegTree<T> { // 親へのアクセス:(n - 1) / 2 // 子へのアクセス:n * 2 + 1、n * 2 + 2 int n = 2; // 要素(葉)の数 int n2; // 全ノード数 T NA; List<T> list; BiFunction<T, T, T> func; /** * 初期化 O(N) * @param num 要素(葉)の数 * @param na 無効とみなせる値 * @param func 区間に対する操作が可能な関数(戻り値は新規オブジェクト) */ public SegTree(int num, T na, BiFunction<T, T, T> func) { while (n < num) n <<= 1; n2 = n * 2 - 1; NA = na; list = new ArrayList<T>(n2); for (int i = 0; i < n2; i++) list.add(NA); this.func = func; } /** * 更新 O(logN) * @param i インデックス(0~n-1) * @param x 更新値 */ void update(int i, T x) { i += n - 1; // arr上でのインデックス list.set(i, x); while (i > 0) { i = (i - 1) / 2; list.set(i, func.apply(list.get(i * 2 + 1), list.get(i * 2 + 2))); } } /** * 取得 O(logN) * インデックスl以上r未満の区間の値 */ T query(int l, int r) { return query(l, r, 0, 0, n); } /** * 取得 O(logN) * インデックスl以上r未満の区間の値、beg, endにはノードkに対応する区間 * query(l, r, 0, 0, n); */ private T query(int l, int r, int k, int beg, int end) { if (end <= l || r <= beg) return NA; // 交差しない if (l <= beg && end <= r) return list.get(k); // 完全に含む T v1 = query(l, r, k * 2 + 1, beg, (beg + end) / 2); T v2 = query(l, r, k * 2 + 2, (beg + end) / 2, end); return func.apply(v1, v2); } } }