結果
問題 | No.902 Query ζone |
ユーザー | chocorusk |
提出日時 | 2019-10-06 22:58:18 |
言語 | C++14 (gcc 12.3.0 + boost 1.83.0) |
結果 |
WA
|
実行時間 | - |
コード長 | 8,163 bytes |
コンパイル時間 | 2,227 ms |
コンパイル使用メモリ | 143,868 KB |
実行使用メモリ | 47,296 KB |
最終ジャッジ日時 | 2024-10-11 18:55:03 |
合計ジャッジ時間 | 29,940 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge3 |
(要ログイン)
テストケース
テストケース表示入力 | 結果 | 実行時間 実行使用メモリ |
---|---|---|
testcase_00 | AC | 2 ms
5,248 KB |
testcase_01 | WA | - |
testcase_02 | WA | - |
testcase_03 | WA | - |
testcase_04 | WA | - |
testcase_05 | WA | - |
testcase_06 | WA | - |
testcase_07 | WA | - |
testcase_08 | WA | - |
testcase_09 | WA | - |
testcase_10 | WA | - |
testcase_11 | WA | - |
testcase_12 | WA | - |
testcase_13 | WA | - |
testcase_14 | WA | - |
testcase_15 | WA | - |
testcase_16 | WA | - |
testcase_17 | WA | - |
testcase_18 | WA | - |
testcase_19 | WA | - |
ソースコード
#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, ll> P; /* template<typename Monoid=int> struct LinkCutTreemyon{ using F=function<Monoid(Monoid, Monoid)>; using S=function<Monoid(Monoid)>; struct Node{ Node *l, *r, *p; int idx; Monoid key, sum; set<int> cst; bool rev; int sz; bool is_root(){ return !p || (p->l!=this && p->r!=this); } Node(int idx, const Monoid &key):idx(idx), key(key), sum(key), sz(1), l(nullptr), r(nullptr), p(nullptr), rev(false) {} }; const Monoid M1; const F f; const S s; LinkCutTreemyon():LinkCutTreemyon([](Monoid a, Monoid b){ return a+b;}, [](Monoid a){ return a;}, Monoid()){} LinkCutTreemyon(const F &f, const S &s, const Monoid &M1):f(f), s(s), M1(M1){} Node *make_node(int idx, const Monoid &v=Monoid()){ return new Node(idx, v); } void toggle(Node *t){ assert(t); swap(t->l, t->r); t->sum=s(t->sum); t->rev^=true; } void push(Node *t){ if(t->rev){ if(t->l) toggle(t->l); if(t->r) toggle(t->r); t->rev=false; } } void update(Node *t){ t->sz=1; t->sum=t->key; if(t->l) t->sz+=t->l->sz, t->sum=f(t->l->sum, t->sum); if(t->r) t->sz+=t->r->sz, t->sum=f(t->sum, t->r->sum); } void rotr(Node *t){ auto *x=t->p, *y=x->p; if((x->l=t->r)) t->r->p=x; t->r=x, x->p=t; update(x), update(t); if((t->p=y)){ if(y->l==x) y->l=t; if(y->r==x) y->r=t; update(y); } } void rotl(Node *t){ auto *x=t->p, *y=x->p; if((x->r=t->l)) t->l->p=x; t->l=x, x->p=t; update(x), update(t); if((t->p=y)){ if(y->l==x) y->l=t; if(y->r==x) y->r=t; update(y); } } void splay(Node* t){ push(t); while(!t->is_root()){ auto *q=t->p; if(q->is_root()){ push(q), push(t); if(q->l==t) rotr(t); else rotl(t); }else{ auto *r=q->p; push(r), push(q), push(t); if(r->l==q){ if(q->l==t) rotr(q), rotr(t); else rotl(t), rotr(t); }else{ if(q->r==t) rotl(q), rotl(t); else rotr(t), rotl(t); } } } } Node *expose(Node *t){ Node *rp=nullptr; for(Node *cur=t; cur; cur=cur->p){ splay(cur); if(cur->r) cur->cst.insert(cur->r->idx); if(rp) cur->cst.erase(rp->idx); cur->r=rp; update(cur); rp=cur; } splay(t); return rp; } void link(Node *child, Node *parent){ expose(child); expose(parent); child->p=parent; if(parent->r) parent->cst.insert(parent->r->idx); parent->r=child; update(parent); } void cut(Node *child){ expose(child); auto *parent=child->l; child->l=nullptr; parent->p=nullptr; update(child); } void evert(Node *t){ expose(t); toggle(t); push(t); } Node *lca(Node *u, Node *v){ if(get_root(u)!=get_root(v)) return nullptr; expose(u); return expose(v); } Node *get_root(Node *x){ expose(x); while(x->l){ push(x); x=x->l; } return x; } bool comp(Node *u, Node *v, Node *p){ if(p==u) return true; else if(p==v) return false; else if(p->r==u) return true; else if(p->r==v) return false; else if() } }; */ template<typename Monoid=int> struct LinkCutTree{ using F=function<Monoid(Monoid, Monoid)>; using S=function<Monoid(Monoid)>; struct Node{ Node *l, *r, *p; int idx; Monoid key, sum; bool rev; int sz; bool is_root(){ return !p || (p->l!=this && p->r!=this); } Node(int idx, const Monoid &key):idx(idx), key(key), sum(key), sz(1), l(nullptr), r(nullptr), p(nullptr), rev(false) {} }; const Monoid M1; const F f; const S s; LinkCutTree():LinkCutTree([](Monoid a, Monoid b){ return a+b;}, [](Monoid a){ return a;}, Monoid()){} LinkCutTree(const F &f, const S &s, const Monoid &M1):f(f), s(s), M1(M1){} Node *make_node(int idx, const Monoid &v=Monoid()){ return new Node(idx, v); } void toggle(Node *t){ assert(t); swap(t->l, t->r); t->sum=s(t->sum); t->rev^=true; } void push(Node *t){ if(t->rev){ if(t->l) toggle(t->l); if(t->r) toggle(t->r); t->rev=false; } } void update(Node *t){ t->sz=1; t->sum=t->key; if(t->l) t->sz+=t->l->sz, t->sum=f(t->l->sum, t->sum); if(t->r) t->sz+=t->r->sz, t->sum=f(t->sum, t->r->sum); } void rotr(Node *t){ auto *x=t->p, *y=x->p; if((x->l=t->r)) t->r->p=x; t->r=x, x->p=t; update(x), update(t); if((t->p=y)){ if(y->l==x) y->l=t; if(y->r==x) y->r=t; update(y); } } void rotl(Node *t){ auto *x=t->p, *y=x->p; if((x->r=t->l)) t->l->p=x; t->l=x, x->p=t; update(x), update(t); if((t->p=y)){ if(y->l==x) y->l=t; if(y->r==x) y->r=t; update(y); } } void splay(Node* t){ push(t); while(!t->is_root()){ auto *q=t->p; if(q->is_root()){ push(q), push(t); if(q->l==t) rotr(t); else rotl(t); }else{ auto *r=q->p; push(r), push(q), push(t); if(r->l==q){ if(q->l==t) rotr(q), rotr(t); else rotl(t), rotr(t); }else{ if(q->r==t) rotl(q), rotl(t); else rotr(t), rotl(t); } } } } Node *expose(Node *t){ Node *rp=nullptr; for(Node *cur=t; cur; cur=cur->p){ splay(cur); cur->r=rp; update(cur); rp=cur; } splay(t); return rp; } void link(Node *child, Node *parent){ expose(child); expose(parent); child->p=parent; parent->r=child; update(parent); } void cut(Node *child){ expose(child); auto *parent=child->l; child->l=nullptr; parent->p=nullptr; update(child); } void evert(Node *t){ expose(t); toggle(t); push(t); } Node *lca(Node *u, Node *v){ if(get_root(u)!=get_root(v)) return nullptr; expose(u); return expose(v); } Node *get_root(Node *x){ expose(x); while(x->l){ push(x); x=x->l; } return x; } Node *get_kth(Node *v, int k){ expose(v); while(v){ push(v); if(v->r && v->r->sz>k){ v=v->r; }else{ if(v->r) k-=v->r->sz; if(k==0) return v; k--; v=v->l; } } return nullptr; } bool comp(Node *u, Node *v){ auto *p=lca(u, v); if(p==u) return true; else if(p==v) return false; expose(p); int d=p->sum.first; return get_kth(u, 2*(d+1))->idx < get_kth(v, 2*(d+1))->idx; } }; int main() { int n; cin>>n; using LCT=LinkCutTree<P>; auto f=[](P a, P b){ return P(a.first+b.first, a.second+b.second);}; LCT lct(f, [](P a){ return a;}, P(0, 0)); vector<LCT::Node*> nodev(n), nodee(n-1); for(int i=0; i<n; i++){ nodev[i]=lct.make_node(i, P(0, 0)); } int a[100010], b[100010]; ll w[100010]; vector<vector<P>> g(n); map<P, int> mp; for(int i=0; i<n-1; i++){ cin>>a[i]>>b[i]>>w[i]; if(a[i]>b[i]) swap(a[i], b[i]); mp[{a[i], b[i]}]=i; g[a[i]].push_back({b[i], i}); g[b[i]].push_back({a[i], i}); nodee[i]=lct.make_node(n+i, P(1, w[i])); } int ide=n-1; auto dfs=[&](auto dfs, int u, int p)->void{ for(auto q:g[u]){ if(q.first==p) continue; lct.link(nodee[q.second], nodev[u]); lct.link(nodev[q.first], nodee[q.second]); dfs(dfs, q.first, u); } }; dfs(dfs, 0, -1); int Q; cin>>Q; for(int i=0; i<Q; i++){ int t; cin>>t; if(t==1){ int ui, vi, wi; ll xi; cin>>ui>>vi>>wi>>xi; int e; if(ui>vi) e=mp[{vi, ui}]; else e=mp[{ui, vi}]; lct.evert(nodev[vi]); lct.cut(nodev[ui]); lct.cut(nodee[e]); nodee.push_back(lct.make_node(n+ide, P(1, xi))); lct.link(nodee[ide], nodev[vi]); lct.evert(nodev[wi]); lct.link(nodev[wi], nodee[ide]); if(vi>wi) swap(vi, wi); mp[{vi, wi}]=ide; ide++; }else{ int k; cin>>k; vector<int> vx(k); for(int j=0; j<k; j++){ cin>>vx[j]; } sort(vx.begin(), vx.end(), [&](int x, int y){ return lct.comp(nodev[x], nodev[y]);}); ll ans=0; for(int j=0; j<k; j++){ int x=vx[j], y; if(j==k-1) y=vx[0]; else y=vx[j+1]; lct.evert(nodev[x]); lct.expose(nodev[y]); ans+=nodev[y]->sum.second; } ans/=2; cout<<ans<<endl; } } return 0; }