Advertisement
welleyth

IATI 2022 Qual F

Oct 31st, 2022 (edited)
790
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.52 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #include <ext/pb_ds/assoc_container.hpp>
  3. #include <ext/pb_ds/tree_policy.hpp>
  4.  
  5. using namespace std;
  6. using namespace __gnu_pbds;
  7.  
  8. #define int long long
  9. #define mp make_pair
  10. #define pb push_back
  11.  
  12. constexpr int N = (int)1e5 + 111;
  13. constexpr int INF = (int)1e16 + 11123;
  14. constexpr int md = (int)998244353;
  15.  
  16. #pragma GCC optimize("Ofast")
  17. #pragma GCC optimize("unroll-loops")
  18. #pragma GCC target("avx2")
  19.  
  20. vector<pair<int,int>> g[N];
  21. int sz[N];
  22. bool wasCentroid[N];
  23. int leader[20][N];
  24. int d[20][N];
  25. int tin[20][N],tout[20][N];
  26. multiset<int> st[20][N];
  27. bool opened[N];
  28.  
  29. struct node{
  30.     int mn = 0;
  31.     int val = INF;
  32.     bool is = false;
  33.     int w = 0;
  34.     node(){}
  35.     node(node a,node b){
  36.         mn = 0;
  37.         is = false;
  38.         w = 0;
  39.         val = INF;
  40.         mn = min(a.mn,b.mn);
  41.         if(a.is)
  42.             val = min(val,a.val);
  43.         if(b.is)
  44.             val = min(val,b.val);
  45.         is = a.is | b.is;
  46.     }
  47.     int get(){
  48.         return val;
  49.     }
  50. };
  51.  
  52. struct SegTree{
  53.     vector<node> t;
  54.     int n;
  55.     SegTree(){}
  56.     SegTree(int n):n(n){
  57.         t.resize(4*(n+1),node());
  58.     }
  59.     void push(int v){
  60.         t[v<<1].mn += t[v].w;
  61.         t[v<<1|1].mn += t[v].w;
  62.         t[v<<1].val += t[v].w;
  63.         t[v<<1|1].val += t[v].w;
  64.         t[v<<1].w += t[v].w;
  65.         t[v<<1|1].w += t[v].w;
  66.         t[v].w = 0;
  67.         return;
  68.     }
  69.     void upd(int v,int l,int r,int tl,int tr,int x){
  70.         if(l > r || tl > tr)
  71.             return;
  72.         if(l == tl && r == tr){
  73.             t[v].mn += x;
  74.             t[v].val += x;
  75.             t[v].w += x;
  76.             return;
  77.         }
  78.         push(v);
  79.         int m = (l+r)>>1;
  80.         upd(v<<1,l,m,tl,min(tr,m),x);
  81.         upd(v<<1|1,m+1,r,max(tl,m+1),tr,x);
  82.         t[v] = node(t[v<<1],t[v<<1|1]);
  83.         return;
  84.     }
  85.     void upd(int l,int r,int x){
  86.         upd(1,0,n-1,l,r,x);
  87.         return;
  88.     }
  89.     void changeState(int v,int l,int r,int pos){
  90.         if(l == r){
  91.             t[v].is ^= 1;
  92.             if(t[v].is)
  93.                 t[v].val = t[v].mn;
  94.             else
  95.                 t[v].val = INF;
  96.             return;
  97.         }
  98.         int m = (l+r)>>1;
  99.         push(v);
  100.         if(pos <= m)
  101.             changeState(v<<1,l,m,pos);
  102.         else
  103.             changeState(v<<1|1,m+1,r,pos);
  104.         t[v] = node(t[v<<1],t[v<<1|1]);
  105.         return;
  106.     }
  107.     void changeState(int pos){
  108.         changeState(1,0,n-1,pos);
  109.         return;
  110.     }
  111.     int get(int v,int l,int r,int pos){
  112.         if(l == r){
  113.             assert(pos == l);
  114.             return t[v].mn;
  115.         }
  116.         push(v);
  117.         int m = (l+r)>>1;
  118.         if(pos <= m)
  119.             return get(v<<1,l,m,pos);
  120.         else
  121.             return get(v<<1|1,m+1,r,pos);
  122.     }
  123.     int get(int pos){
  124.         return get(1,0,n-1,pos);
  125.     }
  126. } t[N];
  127.  
  128. void dfs1(int v,int pr = -1){
  129.     sz[v] = 1;
  130.     for(auto&[to,w] : g[v]){
  131.         if(!wasCentroid[to] && pr != to){
  132.             dfs1(to,v);
  133.             sz[v] += sz[to];
  134.         }
  135.     }
  136.     return;
  137. }
  138.  
  139. int dfs2(int v,int S,int pr = -1){
  140.     for(auto&[to,w] : g[v]){
  141.         if(wasCentroid[to] || to == pr)
  142.             continue;
  143.         if(2 * sz[to] > S)
  144.             return dfs2(to,S,v);
  145.     }
  146.     return v;
  147. }
  148.  
  149. void changeLeader(int v,int L,int lvl,int pr = -1){
  150.     leader[lvl][v] = L;
  151.     for(auto&[to,w] : g[v]){
  152.         if(to == pr || wasCentroid[to])
  153.             continue;
  154.         changeLeader(to,L,lvl,v);
  155.     }
  156.     return;
  157. }
  158.  
  159. int timer = 0;
  160.  
  161. void dfs3(int v,int lvl,int pr = -1,bool f = true){
  162.     tin[lvl][v] = timer++;
  163.     int L = leader[lvl][v];
  164.     if(f)
  165.         t[L].upd(tin[lvl][v],tin[lvl][v],d[lvl][v]);
  166.     for(auto&[to,w] : g[v]){
  167.         if(wasCentroid[to] || to == pr)
  168.             continue;
  169.         if(f)
  170.             d[lvl][to] = d[lvl][v] + w;
  171.         dfs3(to,lvl,v);
  172.     }
  173.     tout[lvl][v] = timer;
  174.     return;
  175. }
  176.  
  177. void buildCentroid(int v,int pr = -1,int lvl = 0){
  178.     dfs1(v,pr);
  179.     int cur = dfs2(v,sz[v],pr);
  180.     wasCentroid[cur] = true;
  181.     changeLeader(cur,cur,lvl);
  182.     timer = 0;
  183.     dfs3(cur,lvl,-1,false);
  184.     t[cur] = SegTree(timer);
  185.     timer = 0;
  186.     d[lvl][cur] = 0;
  187.     dfs3(cur,lvl);
  188.     for(auto&[to,w] : g[cur]){
  189.         if(!wasCentroid[to]){
  190.             buildCentroid(to,v,lvl+1);
  191.         }
  192.     }
  193.     return;
  194. }
  195.  
  196. int getDistVertexCentroid(int v,int lvl){
  197.     int pos = tin[lvl][v];
  198.     int centroid = leader[lvl][v];
  199.     return t[centroid].get(pos);
  200. }
  201.  
  202. int getClosestOpenned(int v){
  203.     int ans = INF;
  204.     for(int i = 19; i >= 0; i--){
  205.         if(leader[i][v] == 0)
  206.             continue;
  207.         int L = leader[i][v];
  208.         int cur = t[L].t[1].get() + getDistVertexCentroid(v,i);
  209.         ans = min(ans,cur);
  210.     }
  211.     return (ans > (int)1e15 ? -1 : ans);
  212. }
  213.  
  214. int upper(int a,int b,int lvl){
  215.     return tin[lvl][a] <= tin[lvl][b] ? a : b;
  216. }
  217.  
  218. void ChangeRestState(int v){
  219.     for(int i = 19; i >= 0; i--){
  220.         if(leader[i][v] == 0)
  221.             continue;
  222.         int L = leader[i][v];
  223.         t[L].changeState(tin[i][v]);
  224.     }
  225.     return;
  226. }
  227.  
  228. map<pair<int,int>,int> cost;
  229.  
  230. void ChangeEdgeWeight(int a,int b,int c){
  231.     int delta = c - cost[mp(a,b)];
  232.     cost[mp(a,b)] = cost[mp(b,a)] = c;
  233.     for(int i = 19; i >= 0; i--){
  234.         if(leader[i][a] == 0)
  235.             continue;
  236.         int L = leader[i][a];
  237.         if(leader[i][a] == leader[i][b]){
  238.             int u = upper(a,b,i);
  239.             int v = a^b^u;
  240.             t[L].upd(tin[i][v],tout[i][v]-1,delta);
  241.         }
  242.     }
  243.     return;
  244. }
  245.  
  246. void solve(){
  247.     int n,q;
  248.     cin >> n >> q;
  249.  
  250.     for(int i = 1; i < n; i++){
  251.         int a,b,c;
  252.         cin >> a >> b >> c;
  253.         cost[mp(a,b)] = cost[mp(b,a)] = c;
  254.         g[a].pb(mp(b,c));
  255.         g[b].pb(mp(a,c));
  256.     }
  257.  
  258.     /// build centroid decomposition
  259.     buildCentroid(1);
  260.  
  261.     for(int i = 0; i < q; i++){
  262.         int tp;
  263.         cin >> tp;
  264.         if(tp == 1){ /// get min dist
  265.             int v;
  266.             cin >> v;
  267.             cout << getClosestOpenned(v) << "\n";
  268.         }
  269.         if(tp == 2){ /// open/close restaurant
  270.             int v;
  271.             cin >> v;
  272.             ChangeRestState(v);
  273.         }
  274.         if(tp == 3){
  275.             int a,b,c;
  276.             cin >> a >> b >> c;
  277.             ChangeEdgeWeight(a,b,c);
  278.         }
  279.     }
  280.  
  281.     return;
  282. }
  283.  
  284. signed main(){
  285.     ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
  286.     int tests = 1;
  287. //    cin >> tests;
  288.     for(int test = 1; test <= tests; test++){
  289.         solve();
  290.     }
  291.     return 0;
  292. }
  293.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement