結果
問題 | No.650 行列木クエリ |
ユーザー | chocorusk |
提出日時 | 2019-10-01 19:02:13 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 144 ms / 2,000 ms |
コード長 | 4,423 bytes |
コンパイル時間 | 1,451 ms |
コンパイル使用メモリ | 127,156 KB |
実行使用メモリ | 25,164 KB |
最終ジャッジ日時 | 2024-10-03 05:45:27 |
合計ジャッジ時間 | 2,759 ms |
ジャッジサーバーID (参考情報) |
judge1 / judge5 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
6,820 KB |
testcase_01 | AC | 59 ms
7,040 KB |
testcase_02 | AC | 144 ms
20,228 KB |
testcase_03 | AC | 2 ms
6,820 KB |
testcase_04 | AC | 60 ms
7,040 KB |
testcase_05 | AC | 139 ms
20,052 KB |
testcase_06 | AC | 2 ms
6,820 KB |
testcase_07 | AC | 2 ms
6,816 KB |
testcase_08 | AC | 61 ms
7,936 KB |
testcase_09 | AC | 131 ms
25,164 KB |
testcase_10 | AC | 2 ms
6,820 KB |
ソースコード
#include <cstdio> #include <cstring> #include <iostream> #include <string> #include <cmath> #include <bitset> #include <vector> #include <map> #include <set> #include <queue> #include <deque> #include <algorithm> #include <complex> #include <unordered_map> #include <unordered_set> #include <random> #include <cassert> #include <fstream> #include <utility> #include <functional> #define popcount __builtin_popcount using namespace std; typedef long long int ll; typedef pair<int, int> P; const ll MOD=1e9+7; struct Matrix{ ll a, b, c, d; Matrix():a(1), b(0), c(0), d(1){} Matrix(ll a, ll b, ll c, ll d):a(a), b(b), c(c), d(d){} }; template<typename Monoid> struct SegmentTree{ using F=function<Monoid(Monoid, Monoid)>; int sz; vector<Monoid> seg; const F f; const Monoid e; SegmentTree(int n, const F f, const Monoid &e): f(f), e(e){ sz=1; while(sz<n) sz<<=1; seg.resize(2*sz, e); } SegmentTree(int n, const F f, const Monoid &e, vector<Monoid> v): f(f), e(e){ sz=1; while(sz<n) sz<<=1; seg.resize(2*sz, e); for(int i=0; i<n; i++) seg[i+sz]=v[i]; for(int i=sz-1; i>=1; i--){ seg[i]=f(seg[2*i], seg[2*i+1]); } } void update(int k, const Monoid &x){ k+=sz; seg[k]=x; while(k>1){ k>>=1; seg[k]=f(seg[2*k], seg[2*k+1]); } } Monoid query(int a, int b){ a+=sz, b+=sz; Monoid retl=e, retr=e; for(;a<b; a>>=1, b>>=1){ if(b&1) retr=f(seg[--b], retr); if(a&1) retl=f(retl, seg[a++]); } return f(retl, retr); } Monoid operator[](const int &k) const{ return seg[k+sz]; } }; template< typename G > struct HeavyLightDecomposition { G &g; vector< int > sz, in, out, head, rev, par; HeavyLightDecomposition(G &g) : g(g), sz(g.size()), in(g.size()), out(g.size()), head(g.size()), rev(g.size()), par(g.size()) {} void dfs_sz(int idx, int p) { par[idx] = p; sz[idx] = 1; if(g[idx].size() && g[idx][0] == p) swap(g[idx][0], g[idx].back()); for(auto &to : g[idx]) { if(to == p) continue; dfs_sz(to, idx); sz[idx] += sz[to]; if(sz[g[idx][0]] < sz[to]) swap(g[idx][0], to); } } void dfs_hld(int idx, int par, int ×) { in[idx] = times++; rev[in[idx]] = idx; for(auto &to : g[idx]) { if(to == par) continue; head[to] = (g[idx][0] == to ? head[idx] : to); dfs_hld(to, idx, times); } out[idx] = times; } void build() { dfs_sz(0, -1); int t = 0; dfs_hld(0, -1, t); } int la(int v, int k) { while(1) { int u = head[v]; if(in[v] - k >= in[u]) return rev[in[v] - k]; k -= in[v] - in[u] + 1; v = par[u]; } } int lca(int u, int v) { for(;; v = par[head[v]]) { if(in[u] > in[v]) swap(u, v); if(head[u] == head[v]) return u; } } template< typename T, typename Q, typename F > T query(int u, int v, const T &ti, const Q &q, const F &f, bool edge = false) { T l = ti;//r = ti; for(;; v = par[head[v]]) { //if(in[u] > in[v]) swap(u, v), swap(l, r); if(head[u] == head[v]) break; l = f(q(in[head[v]], in[v] + 1), l); } return f(q(in[u] + edge, in[v] + 1), l); // return {f(q(in[u] + edge, in[v] + 1), l), r}; } template< typename Q > void add(int u, int v, const Q &q, bool edge = false) { for(;; v = par[head[v]]) { if(in[u] > in[v]) swap(u, v); if(head[u] == head[v]) break; q(in[head[v]], in[v] + 1); } q(in[u] + edge, in[v] + 1); } }; int main() { int n; cin>>n; vector<vector<int>> g(n); int a[100010], b[100010]; for(int i=0; i<n-1; i++){ cin>>a[i]>>b[i]; g[a[i]].push_back(b[i]); g[b[i]].push_back(a[i]); } HeavyLightDecomposition<vector<vector<int>>> hld(g); hld.build(); Matrix e; using F=function<Matrix(Matrix, Matrix)>; auto f=[&](Matrix a, Matrix b){ Matrix c((a.a*b.a+a.b*b.c)%MOD, (a.a*b.b+a.b*b.d)%MOD, (a.c*b.a+a.d*b.c)%MOD, (a.c*b.b+a.d*b.d)%MOD); return c; }; SegmentTree<Matrix> seg(n, f, e); using Q=function<Matrix(int, int)>; auto q=[&](int a, int b){ return seg.query(a, b);}; int qc; cin>>qc; for(int t=0; t<qc; t++){ char c; cin>>c; if(c=='g'){ int i, j; cin>>i>>j; Matrix ans=hld.query<Matrix, Q, F>(i, j, e, q, f, true); cout<<ans.a<<" "<<ans.b<<" "<<ans.c<<" "<<ans.d<<endl; }else{ int i; Matrix x; cin>>i>>x.a>>x.b>>x.c>>x.d; if(hld.in[a[i]]>hld.in[b[i]]) swap(a[i], b[i]); seg.update(hld.in[b[i]], x); } } return 0; }