結果
| 問題 |
No.650 行列木クエリ
|
| コンテスト | |
| ユーザー |
chocorusk
|
| 提出日時 | 2019-10-01 19:28:18 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 123 ms / 2,000 ms |
| コード長 | 4,337 bytes |
| コンパイル時間 | 1,531 ms |
| コンパイル使用メモリ | 126,404 KB |
| 実行使用メモリ | 25,216 KB |
| 最終ジャッジ日時 | 2024-10-03 05:45:50 |
| 合計ジャッジ時間 | 2,418 ms |
|
ジャッジサーバーID (参考情報) |
judge4 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 10 |
コンパイルメッセージ
main.cpp: In function 'int main()':
main.cpp:171:17: warning: capture of variable 'MOD' with non-automatic storage duration
171 | auto f=[MOD](Matrix a, Matrix b){
| ^~~
main.cpp:25:10: note: 'const ll MOD' declared here
25 | const ll MOD=1e9+7;
| ^~~
ソースコード
#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 &e, const Q &q, const F &f, bool edge = false) {
T l = e;//r = e;
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;
auto f=[MOD](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);
auto q=[&](int a, int b){ return seg.query(a, b);};
int Q; cin>>Q;
for(int t=0; t<Q; t++){
char c;
cin>>c;
if(c=='g'){
int i, j;
cin>>i>>j;
Matrix ans=hld.query(i, j, e, q, f, true);
cout<<ans.a<<" "<<ans.b<<" "<<ans.c<<" "<<ans.d<<endl;
}else{
int i, x, y, z, w;
cin>>i>>x>>y>>z>>w;
if(hld.in[a[i]]>hld.in[b[i]]) swap(a[i], b[i]);
seg.update(hld.in[b[i]], Matrix(x, y, z, w));
}
}
return 0;
}
chocorusk