結果

問題 No.1030 だんしんぐぱーりない
ユーザー ks2m
提出日時 2020-04-17 22:50:41
言語 Java
(openjdk 23)
結果
AC  
実行時間 1,666 ms / 2,000 ms
コード長 5,501 bytes
コンパイル時間 2,852 ms
コンパイル使用メモリ 91,772 KB
実行使用メモリ 97,404 KB
最終ジャッジ日時 2024-10-03 14:36:39
合計ジャッジ時間 44,521 ms
ジャッジサーバーID
(参考情報)
judge1 / judge5
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2
other AC * 40
権限があれば一括ダウンロードができます

ソースコード

diff #
プレゼンテーションモードにする

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++;
}
}
}
/**
* I0≦Isize
*/
public Obj get(int i) {
return arr[first[i] + n - 1];
}
/**
* A,BLCA0≦A,Bsize
*/
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 + 1n * 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 0n-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)
* lr
*/
T query(int l, int r) {
return query(l, r, 0, 0, n);
}
/**
* O(logN)
* lrbeg, endk
* 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);
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0