제출 #1253469

#제출 시각아이디문제언어결과실행 시간메모리
1253469GeforgsGrapevine (NOI22_grapevine)C++20
0 / 100
1096 ms194552 KiB
#include <iostream> #include <iomanip> #include <vector> #include <cmath> #include <algorithm> #include <set> #include <queue> #include <map> #include <unordered_map> #include <stack> #include <bit> #include <bitset> #include <string> #include <cstring> #include <iterator> #include <random> #define ll long long #define ld long double #define inf (ll)(2*1e18) #define sort(a) sort(a.begin(), a.end()) #define reverse(a) reverse(a.begin(), a.end()) #define pb push_back #define endl "\n" using namespace std; struct Node{ ll parent, level; vector<ll> tin; vector<ll> tout; vector<ll> a; vector<ll> b; vector<ll> push; }; void DFS1(ll id, ll last, ll l, vector<ll>& level, vector<vector<ll>>& a, vector<ll>& sz){ sz[id] = 1; for(auto el: a[id]){ if(el == last or level[el] < l) continue; DFS1(el, id, l, level, a, sz); sz[id] += sz[el]; } } ll getCentroid(ll id, ll last, ll cnt, ll l, vector<ll>& level, vector<vector<ll>>& a, vector<ll>& sz){ for(auto el: a[id]){ if(el == last or level[el] < l) continue; if(2*sz[el] >= cnt){ return getCentroid(el, id, cnt, l, level, a, sz); } } return id; } void DFS2(ll id, ll last, ll l, ll& time, vector<ll>& level, vector<vector<ll>>& a, vector<Node>& c, vector<ll>& d){ c[d[id]].tin.pb(++time); for(auto el: a[id]){ if(el == last or level[el] < l) continue; DFS2(el, id, l, time, level, a, c, d); } c[d[id]].tout.pb(time); } void build(ll id, ll last, ll l, vector<ll>& level, vector<vector<ll>>& a, vector<Node>& c, vector<ll>& sz, vector<ll>& d){ DFS1(id, id, l, level, a, sz); ll centroid = getCentroid(id, id, sz[id], l, level, a, sz), time=-1; c.pb(Node()); d[centroid] = c.size()-1; c.back().parent = last; c.back().level = l; c.back().a.resize(4*sz[id]); c.back().b.resize(4*sz[id], inf); c.back().push.resize(4*sz[id]); level[centroid] = l; for(auto el: a[centroid]){ if(level[el] < l) continue; build(el, d[centroid], l+1, level, a, c, sz, d); } DFS2(centroid, centroid, l, time, level, a, c, d); } bool isAncestor(ll id, ll x, ll y, vector<Node>& c){ ll l = c[id].level; return c[x].tin[l] <= c[y].tin[l] and c[y].tout[l] <= c[x].tout[l]; } void push(ll id, vector<ll>& a, vector<ll>& b, vector<ll>& p){ a[2*id] += p[id]; p[2*id] += p[id]; if(b[2*id] != inf) b[2*id] += p[id]; a[2*id+1] += p[id]; p[2*id+1] += p[id]; if(b[2*id+1] != inf) b[2*id+1] += p[id]; p[id] = 0; } void add(ll id, ll l, ll r, ll tl, ll tr, ll val, vector<ll>& a, vector<ll>& b, vector<ll>& p){ if(r < tl or tr < l) return; if(tl <= l and r <= tr){ a[id] += val; p[id] += val; if(b[id] != inf) b[id] += val; return; } push(id, a, b, p); ll m=(l+r)/2; add(2*id, l, m, tl, tr, val, a, b, p); add(2*id+1, m+1, r, tl, tr, val, a, b, p); b[id] = min(b[2*id], b[2*id+1]); } void add(ll id, ll x, ll y, ll w, vector<Node>& c){ if(id == -1) return; if(isAncestor(id, y, x, c)){ swap(x, y); } add(1, 0, c[id].tout[c[id].level], c[y].tin[c[id].level], c[y].tout[c[id].level], w, c[id].a, c[id].b, c[id].push); add(c[id].parent, x, y, w, c); } void rev(ll id, ll l, ll r, ll x, vector<ll>& a, vector<ll>& b, vector<ll>& p){ if(l == r){ if(b[id] == inf){ b[id] = a[id]; }else{ b[id] = inf; } return; } push(id, a, b, p); ll m=(l+r)/2; if(x <= m) rev(2*id, l, m, x, a, b, p); else rev(2*id+1, m+1, r, x, a, b, p); b[id] = min(b[2*id], b[2*id+1]); } ll get(ll id, ll l, ll r, ll x, vector<ll>& a, vector<ll>& b, vector<ll>& p){ if(l == r){ return a[id]; } push(id, a, b, p); ll m=(l+r)/2; if(x <= m) return get(2*id, l, m, x, a, b, p); return get(2*id + 1, m+1, r, x, a, b, p); } ll get(ll id, ll x, vector<Node>& c){ if(id == -1) return inf; ll res = get(c[id].parent, x, c), level=c[id].level; res = min(res, c[id].b[1] + get(1, 0, c[id].tout[level], c[x].tin[level], c[id].a, c[id].b, c[id].push)); return res; } void rev(ll id, ll x, vector<Node>& c){ if(id == -1) return; ll level = c[id].level; rev(1, 0, c[id].tout[level], c[x].tin[level], c[id].a, c[id].b, c[id].push); rev(c[id].parent, x, c); } void solve(){ ll n, q, i, x, y, w, type, res; cin>>n>>q; vector<vector<ll>> a(n); vector<pair<pair<ll, ll>, ll>> b(n-1); vector<ll> level(n, inf); vector<Node> c; vector<ll> sz(n); vector<ll> d(n); for(i=0;i<n-1;++i){ cin>>x>>y>>w; --x; --y; a[x].pb(y); a[y].pb(x); b[i] = {{x, y}, w}; } build(0, -1, 0, level, a, c, sz, d); for(i=0;i<n;++i){ reverse(c[i].tin); reverse(c[i].tout); } for(i=0;i<n-1;++i){ if(level[b[i].first.first] < level[b[i].first.second]){ x = b[i].first.first; y = b[i].first.second; }else{ y = b[i].first.first; x = b[i].first.second; } add(d[x], d[x], d[y], b[i].second, c); } for(i=0;i<q;++i){ cin>>type; if(type == 1){ cin>>x; --x; x = d[x]; res = get(x, x, c); if(res == inf){ cout<<-1<<endl; }else{ cout<<res<<endl; } }else if(type == 2){ cin>>x; --x; x = d[x]; rev(x, x, c); }else{ cin>>x>>y>>w; --x; --y; if(level[x] > level[y]){ swap(x, y); } } } } int main() { ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); srand(time(nullptr)); ll t=1; // cin>>t; for(;t>0;--t){ solve(); } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...