結果

問題 No.1790 Subtree Deletion
ユーザー 👑 NachiaNachia
提出日時 2021-12-11 17:24:00
言語 Java21
(openjdk 21)
結果
AC  
実行時間 2,031 ms / 3,000 ms
コード長 11,562 bytes
コンパイル時間 5,424 ms
コンパイル使用メモリ 91,636 KB
実行使用メモリ 100,556 KB
最終ジャッジ日時 2023-10-13 18:21:45
合計ジャッジ時間 29,237 ms
ジャッジサーバーID
(参考情報)
judge11 / judge12
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 131 ms
55,680 KB
testcase_01 AC 131 ms
55,828 KB
testcase_02 AC 133 ms
55,584 KB
testcase_03 AC 2,013 ms
96,272 KB
testcase_04 AC 2,031 ms
96,628 KB
testcase_05 AC 2,014 ms
96,640 KB
testcase_06 AC 2,018 ms
96,256 KB
testcase_07 AC 2,011 ms
96,844 KB
testcase_08 AC 961 ms
65,364 KB
testcase_09 AC 1,971 ms
100,556 KB
testcase_10 AC 1,977 ms
96,132 KB
testcase_11 AC 1,980 ms
94,636 KB
testcase_12 AC 1,703 ms
94,800 KB
testcase_13 AC 1,796 ms
90,796 KB
testcase_14 AC 1,053 ms
70,056 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

package nachia.competitive.atcoder;





import java.util.ArrayList;
import java.util.Scanner;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;

public class Main {

	/*
	 * begin
	 *
	 *     AtCoderLibraryForJava by NASU41, suisen-cp and others
	 *     repository : https://github.com/NASU41/AtCoderLibraryForJava
	 *     code : https://github.com/NASU41/AtCoderLibraryForJava/blob/master/LazySegTree/LazySegTree.java
	 *
	 */
	class LazySegTree<S, F> {
	    final int MAX;

	    final int N;
	    final int Log;
	    final java.util.function.BinaryOperator<S> Op;
	    final S E;
	    final java.util.function.BiFunction<F, S, S> Mapping;
	    final java.util.function.BinaryOperator<F> Composition;
	    final F Id;

	    final S[] Dat;
	    final F[] Laz;

	    @SuppressWarnings("unchecked")
	    public LazySegTree(int n, java.util.function.BinaryOperator<S> op, S e, java.util.function.BiFunction<F, S, S> mapping, java.util.function.BinaryOperator<F> composition, F id) {
	        this.MAX = n;
	        int k = 1;
	        while (k < n) k <<= 1;
	        this.N = k;
	        this.Log = Integer.numberOfTrailingZeros(N);
	        this.Op = op;
	        this.E = e;
	        this.Mapping = mapping;
	        this.Composition = composition;
	        this.Id = id;
	        this.Dat = (S[]) new Object[N << 1];
	        this.Laz = (F[]) new Object[N];
	        java.util.Arrays.fill(Dat, E);
	        java.util.Arrays.fill(Laz, Id);
	    }

	    public LazySegTree(S[] dat, java.util.function.BinaryOperator<S> op, S e, java.util.function.BiFunction<F, S, S> mapping, java.util.function.BinaryOperator<F> composition, F id) {
	        this(dat.length, op, e, mapping, composition, id);
	        build(dat);
	    }

	    private void build(S[] dat) {
	        int l = dat.length;
	        System.arraycopy(dat, 0, Dat, N, l);
	        for (int i = N - 1; i > 0; i--) {
	            Dat[i] = Op.apply(Dat[i << 1 | 0], Dat[i << 1 | 1]);
	        }
	    }

	    private void push(int k) {
	        if (Laz[k] == Id) return;
	        int lk = k << 1 | 0, rk = k << 1 | 1;
	        Dat[lk] = Mapping.apply(Laz[k], Dat[lk]);
	        Dat[rk] = Mapping.apply(Laz[k], Dat[rk]);
	        if (lk < N) Laz[lk] = Composition.apply(Laz[k], Laz[lk]);
	        if (rk < N) Laz[rk] = Composition.apply(Laz[k], Laz[rk]);
	        Laz[k] = Id;
	    }

	    private void pushTo(int k) {
	        for (int i = Log; i > 0; i--) push(k >> i);
	    }

	    private void pushTo(int lk, int rk) {
	        for (int i = Log; i > 0; i--) {
	            if (((lk >> i) << i) != lk) push(lk >> i);
	            if (((rk >> i) << i) != rk) push(rk >> i);
	        }
	    }

	    private void updateFrom(int k) {
	        k >>= 1;
	        while (k > 0) {
	            Dat[k] = Op.apply(Dat[k << 1 | 0], Dat[k << 1 | 1]);
	            k >>= 1;
	        }
	    }

	    private void updateFrom(int lk, int rk) {
	        for (int i = 1; i <= Log; i++) {
	            if (((lk >> i) << i) != lk) {
	                int lki = lk >> i;
	                Dat[lki] = Op.apply(Dat[lki << 1 | 0], Dat[lki << 1 | 1]);
	            }
	            if (((rk >> i) << i) != rk) {
	                int rki = (rk - 1) >> i;
	                Dat[rki] = Op.apply(Dat[rki << 1 | 0], Dat[rki << 1 | 1]);
	            }
	        }
	    }

	    public void set(int p, S x) {
	        exclusiveRangeCheck(p);
	        p += N;
	        pushTo(p);
	        Dat[p] = x;
	        updateFrom(p);
	    }

	    public S get(int p) {
	        exclusiveRangeCheck(p);
	        p += N;
	        pushTo(p);
	        return Dat[p];
	    }

	    public S prod(int l, int r) {
	        if (l > r) {
	            throw new IllegalArgumentException(
	                String.format("Invalid range: [%d, %d)", l, r)
	            );
	        }
	        inclusiveRangeCheck(l);
	        inclusiveRangeCheck(r);
	        if (l == r) return E;
	        l += N; r += N;
	        pushTo(l, r);
	        S sumLeft = E, sumRight = E;
	        while (l < r) {
	            if ((l & 1) == 1) sumLeft = Op.apply(sumLeft, Dat[l++]);
	            if ((r & 1) == 1) sumRight = Op.apply(Dat[--r], sumRight);
	            l >>= 1; r >>= 1;
	        }
	        return Op.apply(sumLeft, sumRight);
	    }

	    public S allProd() {
	        return Dat[1];
	    }

	    public void apply(int p, F f) {
	        exclusiveRangeCheck(p);
	        p += N;
	        pushTo(p);
	        Dat[p] = Mapping.apply(f, Dat[p]);
	        updateFrom(p);
	    }

	    public void apply(int l, int r, F f) {
	        if (l > r) {
	            throw new IllegalArgumentException(
	                String.format("Invalid range: [%d, %d)", l, r)
	            );
	        }
	        inclusiveRangeCheck(l);
	        inclusiveRangeCheck(r);
	        if (l == r) return;
	        l += N; r += N;
	        pushTo(l, r);
	        for (int l2 = l, r2 = r; l2 < r2;) {
	            if ((l2 & 1) == 1) {
	                Dat[l2] = Mapping.apply(f, Dat[l2]);
	                if (l2 < N) Laz[l2] = Composition.apply(f, Laz[l2]);
	                l2++;
	            }
	            if ((r2 & 1) == 1) {
	                r2--;
	                Dat[r2] = Mapping.apply(f, Dat[r2]);
	                if (r2 < N) Laz[r2] = Composition.apply(f, Laz[r2]);
	            }
	            l2 >>= 1; r2 >>= 1;
	        }
	        updateFrom(l, r);
	    }

	    public int maxRight(int l, java.util.function.Predicate<S> g) {
	        inclusiveRangeCheck(l);
	        if (!g.test(E)) {
	            throw new IllegalArgumentException("Identity element must satisfy the condition.");
	        }
	        if (l == MAX) return MAX;
	        l += N;
	        pushTo(l);
	        S sum = E;
	        do {
	            l >>= Integer.numberOfTrailingZeros(l);
	            if (!g.test(Op.apply(sum, Dat[l]))) {
	                while (l < N) {
	                    push(l);
	                    l = l << 1;
	                    if (g.test(Op.apply(sum, Dat[l]))) {
	                        sum = Op.apply(sum, Dat[l]);
	                        l++;
	                    }
	                }
	                return l - N;
	            }
	            sum = Op.apply(sum, Dat[l]);
	            l++;
	        } while ((l & -l) != l);
	        return MAX;
	    }

	    public int minLeft(int r, java.util.function.Predicate<S> g) {
	        inclusiveRangeCheck(r);
	        if (!g.test(E)) {
	            throw new IllegalArgumentException("Identity element must satisfy the condition.");
	        }
	        if (r == 0) return 0;
	        r += N;
	        pushTo(r - 1);
	        S sum = E;
	        do {
	            r--;
	            while (r > 1 && (r & 1) == 1) r >>= 1;
	            if (!g.test(Op.apply(Dat[r], sum))) {
	                while (r < N) {
	                    push(r);
	                    r = r << 1 | 1;
	                    if (g.test(Op.apply(Dat[r], sum))) {
	                        sum = Op.apply(Dat[r], sum);
	                        r--;
	                    }
	                }
	                return r + 1 - N;
	            }
	            sum = Op.apply(Dat[r], sum);
	        } while ((r & -r) != r);
	        return 0;
	    }

	    private void exclusiveRangeCheck(int p) {
	        if (p < 0 || p >= MAX) {
	            throw new IndexOutOfBoundsException(
	                String.format("Index %d is not in [%d, %d).", p, 0, MAX)
	            );
	        }
	    }

	    private void inclusiveRangeCheck(int p) {
	        if (p < 0 || p > MAX) {
	            throw new IndexOutOfBoundsException(
	                String.format("Index %d is not in [%d, %d].", p, 0, MAX)
	            );
	        }
	    }

	    // **************** DEBUG **************** //

	    private int indent = 6;

	    public void setIndent(int newIndent) {
	        this.indent = newIndent;
	    }

	    @Override
	    public String toString() {
	        return toSimpleString();
	    }

	    private S[] simulatePushAll() {
	        S[] simDat = java.util.Arrays.copyOf(Dat, 2 * N);
	        F[] simLaz = java.util.Arrays.copyOf(Laz, 2 * N);
	        for (int k = 1; k < N; k++) {
	            if (simLaz[k] == Id) continue;
	            int lk = k << 1 | 0, rk = k << 1 | 1;
	            simDat[lk] = Mapping.apply(simLaz[k], simDat[lk]);
	            simDat[rk] = Mapping.apply(simLaz[k], simDat[rk]);
	            if (lk < N) simLaz[lk] = Composition.apply(simLaz[k], simLaz[lk]);
	            if (rk < N) simLaz[rk] = Composition.apply(simLaz[k], simLaz[rk]);
	            simLaz[k] = Id;
	        }
	        return simDat;
	    }

	    /*
	    public String toDetailedString() {
	        return toDetailedString(1, 0, simulatePushAll());
	    }

	    private String toDetailedString(int k, int sp, S[] dat) {
	        if (k >= N) return indent(sp) + dat[k];
	        String s = "";
	        s += toDetailedString(k << 1 | 1, sp + indent, dat);
	        s += "\n";
	        s += indent(sp) + dat[k];
	        s += "\n";
	        s += toDetailedString(k << 1 | 0, sp + indent, dat);
	        return s;
	    }

	    private static String indent(int n) {
	        StringBuilder sb = new StringBuilder();
	        while (n --> 0) sb.append(' ');
	        return sb.toString();
	    }
	    */

	    public String toSimpleString() {
	        S[] dat = simulatePushAll();
	        StringBuilder sb = new StringBuilder();
	        sb.append('[');
	        for (int i = 0; i < N; i++) {
	            sb.append(dat[i + N]);
	            if (i < N - 1) sb.append(',').append(' ');
	        }
	        sb.append(']');
	        return sb.toString();
	    }
	}
	// end


	class Edge {
		public int to;
		public long a;
	}


	int N;
	ArrayList<ArrayList<Edge>> E;

	int in_time[];
	int out_time[];
	int dfs_time;
	long A[];
	long alist[];


	void dfs(int p, int pre) {
		in_time[p] = dfs_time;
		dfs_time++;
		ArrayList<Edge> nxlist = E.get(p);
		for(int i=0; i<nxlist.size(); i++) {
			Edge nx = nxlist.get(i);
			if(nx.to == pre) continue;
			A[nx.to] = nx.a;
			dfs(nx.to, p);
		}
		out_time[p] = dfs_time;
	}


	void solve() {
		Scanner sc = new Scanner(System.in);

		N = sc.nextInt();
		E = new ArrayList<>();
		for(int i=0; i<N; i++) E.add(new ArrayList<>());
		for(int i=0; i<N-1; i++) {
			int u = sc.nextInt(); u--;
			int v = sc.nextInt(); v--;
			long a = sc.nextLong();
			Edge e1 = new Edge(); e1.to = v; e1.a = a;
			E.get(u).add(e1);
			Edge e2 = new Edge(); e2.to = u; e2.a = a;
			E.get(v).add(e2);
		}

		dfs_time = 0;

		in_time = new int[N];
		out_time = new int[N];
		A = new long[N];
		dfs(0, -1);

		Long rq_init_buf[] = new Long[N];
		for(int i=0; i<N; i++) rq_init_buf[in_time[i]] = Long.valueOf(A[i]);

		Long rq_e = Long.valueOf(0);
		Long rq_id = Long.valueOf(-1);
		BinaryOperator<Long> rq_op = (a, b) -> { return a ^ b; };
		BiFunction<Long, Long, Long> rq_mapping = (f, x) -> { return (f.compareTo(rq_id) == 0) ? x : f; };
		BinaryOperator<Long> rq_composition = (f, x) -> { return (f.compareTo(rq_id) == 0) ? x : f; };
		LazySegTree<Long, Long> rq = new LazySegTree<Long, Long>(rq_init_buf, rq_op, rq_e, rq_mapping, rq_composition, rq_id);

		int Q = sc.nextInt();
		for(int i=0; i<Q; i++) {
			int t = sc.nextInt();
			if(t == 1) {
				int x = sc.nextInt(); x--;
				int l = in_time[x];
				int r = out_time[x];
				rq.apply(l, r, Long.valueOf(0));
			}
			if(t == 2) {
				int x = sc.nextInt(); x--;
				int l = in_time[x] + 1;
				int r = out_time[x];
				long res = rq.prod(l, r);
				System.out.println(res);
			}
		}

		sc.close();
	}



	public static void main(String[] args) {
		Main solver = new Main();
		solver.solve();
	}
}
0