結果
問題 | No.650 行列木クエリ |
ユーザー |
|
提出日時 | 2018-02-10 02:50:08 |
言語 | D (dmd 2.109.1) |
結果 |
TLE
|
実行時間 | - |
コード長 | 3,761 bytes |
コンパイル時間 | 980 ms |
コンパイル使用メモリ | 131,196 KB |
実行使用メモリ | 26,764 KB |
最終ジャッジ日時 | 2024-06-12 23:51:26 |
合計ジャッジ時間 | 5,239 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
sample | AC * 1 |
other | AC * 7 TLE * 1 -- * 2 |
ソースコード
import std.stdio, std.array, std.string, std.conv, std.algorithm;import std.typecons, std.range, std.random, std.math, std.container;import std.numeric, std.bigint, core.bitop, std.bitmanip;immutable long MOD = 10^^9 + 7;alias Mat = Tuple!(long, "a", long, "b", long, "c", long, "d");void main() {auto N = readln.chomp.to!int;auto G = new int[][](N);auto M = new Mat[](N);auto E = new Tuple!(int, int)[](N-1);foreach (i; 0..N-1) {auto s = readln.split.map!(to!int);G[s[0]] ~= s[1];G[s[1]] ~= s[0];E[i] = tuple(s[0], s[1]);}auto P = new int[](N);auto C = new int[](N);int[][] HL;int[] HL_rev = new int[](N);int[][] HLG;int[] HLP;Mat[] HLM;M.fill(Mat(1, 0, 0, 1));int dfs1(int n, int p) {P[n] = p;C[n] = 1;foreach (m; G[n]) if (m != p) C[n] += dfs1(m, n);return C[n];}void dfs2(int n, int g, int p, bool heavy) {if (heavy) {HL[g] ~= n;} else {g = HL.length.to!int;HL ~= [n];}HL_rev[n] = g;int mx = -1;foreach (m; G[n]) if (m != p) mx = max(mx, C[m]);bool h = false;foreach (m; G[n]) {if (m == p) continue;if (!h && C[m] == mx) {h = true;dfs2(m, g, n, true);} else {dfs2(m, g, n, false);}}}void update(int n, Mat mat) {n = E[n][1];M[n] = mat;int g = HL_rev[n];HLM[HL[g][0]] = M[HL[g][0]];foreach (i; 0..HL[g].length.to!int-1) {HLM[HL[g][i+1]] = mul(HLM[HL[g][i]], M[HL[g][i+1]]);}}Mat query(int u, int v) {auto tmp = Mat(1, 0, 0, 1);int ug = HL_rev[u];int vg = HL_rev[v];if (ug == vg) {bool ok = false;foreach (n; HL[ug]) {if (ok) {tmp = mul(tmp, M[n]);}if (n == u) ok = true;if (n == v) return tmp;}}foreach (n; HL[vg]) {tmp = mul(tmp, M[n]);if (n == v) break;}Mat[] ret = [tmp];int cur = P[HL[vg][0]];while (HL_rev[cur] != ug) {ret ~= HLM[cur];cur = P[HL[HL_rev[cur]][0]];}tmp = Mat(1, 0, 0, 1);bool ok = false;foreach (n; HL[ug]) {if (ok) {tmp = mul(tmp, M[n]);}if (n == u) ok = true;if (n == cur) break;}ret ~= tmp;ret.reverse();Mat ans = Mat(1, 0, 0, 1);foreach (mat; ret) {ans = mul(ans, mat);}return ans;}dfs1(0, -1);dfs2(0, 0, -1, false);foreach (i; 0..N-1) {if (P[E[i][0]] == E[i][1]) swap(E[i][0], E[i][1]);}int group = HL.length.to!int;HLM = N.iota.map!(i => Mat(1, 0, 0, 1)).array;HLG = new int[][](group);HLP = new int[](group);HLP[0] = -1;auto Q = readln.chomp.to!int;while (Q--) {auto q = readln.split;if (q[0] == "x") {update(q[1].to!int, Mat(q[2].to!long, q[3].to!long, q[4].to!long, q[5].to!long));} else {auto ans = query(q[1].to!int, q[2].to!int);writeln(ans.a, " ", ans.b, " ", ans.c, " ", ans.d);}}}Mat mul(Mat X, Mat Y) {Mat ret = Mat(X.a * Y.a + X.b * Y.c, X.a * Y.b + X.b * Y.d,X.c * Y.a + X.d * Y.c, X.c * Y.b + X.d * Y.d);ret.a %= MOD;ret.b %= MOD;ret.c %= MOD;ret.d %= MOD;return ret;}