結果
問題 | No.900 aδδitivee |
ユーザー | IKyopro |
提出日時 | 2019-12-23 23:39:05 |
言語 | C++17 (gcc 12.3.0 + boost 1.83.0) |
結果 |
AC
|
実行時間 | 251 ms / 2,000 ms |
コード長 | 4,913 bytes |
コンパイル時間 | 2,614 ms |
コンパイル使用メモリ | 219,164 KB |
実行使用メモリ | 25,936 KB |
最終ジャッジ日時 | 2024-09-19 04:22:33 |
合計ジャッジ時間 | 10,144 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge2 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | AC | 2 ms
5,376 KB |
testcase_02 | AC | 2 ms
5,376 KB |
testcase_03 | AC | 2 ms
5,376 KB |
testcase_04 | AC | 2 ms
5,376 KB |
testcase_05 | AC | 2 ms
5,376 KB |
testcase_06 | AC | 2 ms
5,376 KB |
testcase_07 | AC | 251 ms
21,180 KB |
testcase_08 | AC | 219 ms
21,152 KB |
testcase_09 | AC | 218 ms
21,300 KB |
testcase_10 | AC | 234 ms
21,040 KB |
testcase_11 | AC | 224 ms
21,292 KB |
testcase_12 | AC | 218 ms
21,168 KB |
testcase_13 | AC | 230 ms
21,272 KB |
testcase_14 | AC | 237 ms
21,280 KB |
testcase_15 | AC | 227 ms
21,272 KB |
testcase_16 | AC | 231 ms
21,300 KB |
testcase_17 | AC | 229 ms
21,208 KB |
testcase_18 | AC | 230 ms
21,228 KB |
testcase_19 | AC | 235 ms
21,232 KB |
testcase_20 | AC | 220 ms
21,288 KB |
testcase_21 | AC | 213 ms
21,088 KB |
testcase_22 | AC | 183 ms
25,880 KB |
testcase_23 | AC | 182 ms
25,904 KB |
testcase_24 | AC | 186 ms
25,928 KB |
testcase_25 | AC | 187 ms
25,896 KB |
testcase_26 | AC | 186 ms
25,784 KB |
testcase_27 | AC | 189 ms
25,936 KB |
testcase_28 | AC | 185 ms
25,892 KB |
ソースコード
#include <bits/stdc++.h> using namespace std; using ll = long long; template<class T> using vec = vector<T>; template<class T> using vvec = vector<vec<T>>; template<typename Monoid,typename OperatorMonoid,typename F,typename G,typename H> struct LazySegmentTree { int sz,height; vec<Monoid> data; vec<OperatorMonoid> lazy; const F op; const G homo; const H comp; const Monoid e; const OperatorMonoid Oe; LazySegmentTree(int n,const F op,const G homo,const H comp, const Monoid &e,const OperatorMonoid Oe) : op(op),homo(homo),comp(comp),e(e),Oe(Oe) { sz = 1; height = 0; while(sz<=n) sz <<= 1,height++; data.assign(2*sz,e); lazy.assign(2*sz,Oe); } void set(int k,const Monoid &x) { data[k+sz] = x; } void build() { for(int k=sz-1;k>0;k--) { data[k] = op(data[2*k], data[2*k+1]); } } inline void propagate(int k) { if(lazy[k]!=Oe) { lazy[2*k] = comp(lazy[2*k], lazy[k]); lazy[2*k+1] = comp(lazy[2*k+1], lazy[k]); data[k] = reflect(k); lazy[k] = Oe; } } inline Monoid reflect(int k) { return lazy[k] == Oe? data[k]:homo(data[k],lazy[k]); } inline void recalc(int k) { while(k>>=1) data[k] = op(reflect(2*k), reflect(2*k+1)); } inline void thrust(int k) { for(int i=height;i>0;i--) propagate(k>>i); } void update(int a, int b, const OperatorMonoid &x) { thrust(a+=sz); thrust(b+=sz-1); for(int l=a,r=b+1;l<r;l>>=1,r>>=1) { if(l&1) lazy[l] = comp(lazy[l],x),++l; if(r&1) --r, lazy[r] = comp(lazy[r],x); } recalc(a); recalc(b); } Monoid query(int a, int b) { thrust(a+=sz); thrust(b+=sz-1); Monoid L = e, R = e; for(int l=a, r=b+1;l<r;l>>= 1,r>>=1) { if(l&1) L = op(L,reflect(l++)); if(r&1) R = op(reflect(--r),R); } return op(L,R); } Monoid operator[](const int &k) { return query(k,k+1); } }; struct edge{ int to,id; ll dist; edge(int to,ll dist=1,int id=1):to(to),id(id),dist(dist){}; }; class HeavLightDecomposition{ private: vvec<edge> g; vec<int> sz,in,out,head,par; int pos; void dfs_sz(int cur,int p){ sz[cur] = 1; par[cur] = p; for(auto& e:g[cur]) if(e.to!=p){ dfs_sz(e.to,cur); sz[cur] += sz[e.to]; if(sz[e.to]>sz[g[cur][0].to]) swap(e,g[cur][0]); } } void dfs_hld(int cur,int p){ in[cur] = pos++; for(auto& e:g[cur]) if(e.to!=p){ head[e.to] = (e.to==g[cur][0].to? head[cur]:e.to); dfs_hld(e.to,cur); } out[cur] = pos; } public: HeavLightDecomposition(){} HeavLightDecomposition(int N,int root,vvec<edge> tree): g(tree),sz(N),in(N),out(N),head(N),par(N){ pos = 0; dfs_sz(root,-1); dfs_hld(root,-1); } int getin(int v){return in[v];} int getout(int v){return out[v];} int lca(int u,int v){ while(true){ if(in[u]>in[v]) swap(u,v); if(head[u]==head[v]) return u; v = par[head[v]]; } } template<class T,class G> void update(int v,const T& x,const G& g){ g(in[v]+1,out[v],x); } template<class T,class F,class Q> T query(int u,int v,const T &e,const F& f,const Q& q,bool isedge=false){ T l = e,r = e; while(true){ 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); v = par[head[v]]; } return f(f(q(in[u]+isedge,in[v]+1),l),r); } }; int main(){ cin.tie(0); ios::sync_with_stdio(false); int N; cin >> N; vvec<edge> tree(N); for(int i=0;i<N-1;i++){ int a,b; ll w; cin >> a >> b >> w; tree[a].push_back({b,w}); } HeavLightDecomposition HLD(N,0,tree); struct state{ ll sum,len; }; auto op = [](state L,state R){ return (state){L.sum+R.sum,L.len+R.len}; }; auto homo = [](state S,ll x){ return (state){S.sum+x*S.len,S.len}; }; auto comp = [](ll a, ll b){return a+b;}; state e = {0,0}; LazySegmentTree<state,ll,decltype(op),decltype(homo),decltype(comp)> seg(N,op,homo,comp,(state){0,0},0); for(int i=0;i<N;i++){ for(auto& e:tree[i]){ // cerr << e.to << " " << HLD.getin(e.to) << " " << HLD.getout(e.to) << endl; seg.set(HLD.getin(e.to),(state) {e.dist,1}); } } seg.build(); int Q; cin >> Q; auto q = [&](int l,int r){return seg.query(l,r);}; auto update = [&](int l,int r,ll x){seg.update(l,r,x);}; for(int i=0;i<Q;i++){ int t; cin >> t; if(t==1){ int v; ll w; cin >> v >> w; HLD.update(v,w,update); }else{ int v; cin >> v; state res = HLD.query(0,v,e,op,q,true); cout << res.sum << endl; } } }