willy108

network

Nov 22nd, 2022
887
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.44 KB | None | 0 0
  1.  
  2. #pragma GCC optimize("O3,unroll-loops")
  3. #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")
  4. //misaka and elaina will carry me to master
  5. #include <iostream>
  6. #include <cstdio>
  7. #include <cstring>
  8. #include <cmath>
  9. #include <utility>
  10. #include <cassert>
  11. #include <algorithm>
  12. #include <vector>
  13. #include <functional>
  14. #include <numeric>
  15. #include <set>
  16. #include <array>
  17. #include <queue>
  18. #include <map>
  19. #include <chrono>
  20. #include <random>
  21.  
  22. #define ll long long
  23. #define lb long double
  24. #define sz(x) ((int)(x.size()))
  25. #define all(x) x.begin(), x.end()
  26. #define pb push_back
  27. #define mp make_pair
  28. #define kill(x, s) {if(x){ cout << s << "\n"; return ; }}
  29.  
  30. #ifndef LOCAL
  31. #define cerr while(0) cerr
  32. #endif
  33.  
  34. const lb eps = 1e-9;
  35. const ll mod = 1e9 + 7, ll_max = 1e18;
  36. //const ll mod = (1 << (23)) * 119 +1, ll_max = 1e18;
  37. const int MX = 2e5 +10, int_max = 0x3f3f3f3f;
  38.  
  39. struct {
  40.   template<class T>
  41.   operator T() {
  42.     T x; std::cin >> x; return x;
  43.   }
  44. } in;
  45.  
  46. using namespace std;
  47.  
  48. vector<pair<int, int>> adj[MX];
  49. ll dep[MX], ignored[MX], relevant[MX];
  50. int heavy[MX];
  51. int par[MX];
  52. int n;
  53. int lenn = 0;
  54.  
  55. void gfar(int u, int p){
  56.     relevant[u] = ignored[u] = heavy[u] = 0;
  57.     for(auto [v, w] : adj[u]){
  58.         if(v == p) continue;
  59.         par[v] = u;
  60.         dep[v] = dep[u] + w;
  61.         gfar(v, u);
  62.     }
  63.     sort(all(adj[u]), [&](pair<int, int> a, pair<int, int> b){
  64.             auto [v1, w1] = a;
  65.             auto [v2, w2] = b;
  66.             if(v1 == p || v2 == p) return v1 != p;
  67.             return relevant[v1] + w1 > relevant[v2] + w2;
  68.             });
  69.     if(sz(adj[u]) > 1 || p == 0){
  70.         heavy[u] = adj[u][0].first;
  71.         relevant[u] = relevant[adj[u][0].first] + adj[u][0].second;
  72.     }
  73.     if(sz(adj[u]) > 2 || (p == 0 && sz(adj[u]) > 1)){
  74.         ignored[u] = relevant[adj[u][1].first] + adj[u][1].second;
  75.     }
  76. }
  77.  
  78. void cl(int n){
  79.     for(int i = 0; i<=n; i++){
  80.         dep[i] = par[i] = heavy[i] = ignored[i] = relevant[i] = 0;
  81.         adj[i].clear();
  82.     }
  83. }
  84.  
  85. ll BIT[4][MX];
  86.  
  87. void U(int op, int k, ll v){
  88.     for(; k <= lenn; k+=k&-k){
  89.         BIT[op][k] = max(BIT[op][k], v);
  90.     }
  91. }
  92.  
  93. ll S(int op, int k){
  94.     ll v = -ll_max;
  95.     while(k){
  96.         v = max(v, BIT[op][k]);
  97.         k -= k&-k;
  98.     }
  99.     return v;
  100. }
  101.  
  102. #define gind(x) (lower_bound(all(srt), x ) -srt.begin() + 1)
  103.  
  104.  
  105. int solve(){
  106.     n = in;
  107.     ll L = in;
  108.     cl(n);
  109.     if(n == 0 && L == 0) return 0;
  110.     for(int i = 1; i<n; i++){
  111.         int a = in, b=  in, c = in;
  112.         adj[a].pb({b, c});
  113.         adj[b].pb({a, c});
  114.     }
  115.     gfar(1, 0);
  116.     int rt = 1;
  117.     while(heavy[rt]) rt = heavy[rt];
  118.     cerr << "diam root is " << rt << "\n";
  119.     dep[rt] = 0;
  120.     gfar(rt, 0);
  121.     vector<int> diam;
  122.     for(int i = rt; i; i = heavy[i]){
  123.         diam.pb(i);
  124.     }
  125.    
  126.     {
  127.         vector<ll> poss;
  128.         for (int i = 0; i < sz(diam); i++)
  129.             poss.pb(dep[diam[i]]);
  130.         assert(is_sorted(all(poss)));
  131.        
  132.         ll l = 0, r = relevant[rt] + 1;
  133.         while(l + 1 != r){
  134.             ll mid = (l + r)/2ll;
  135.             //check function
  136.             int yes = 0;
  137.             mid--;
  138.             ll best0 = -ll_max;
  139.             ll best1 = -ll_max;
  140.             ll best2 = -ll_max;
  141.             ll best3 = -ll_max;
  142.             vector<ll> srt;
  143.             for (int i = 0; i < sz(diam); i++){
  144.                 srt.pb(-mid + dep[diam[i]] + ignored[diam[i]] -1); 
  145.             }
  146.             sort(all(srt)); srt.resize(unique(all(srt)) - srt.begin());
  147.             lenn = sz(srt);
  148.             for(int j = 0; j<4; j++){
  149.                 for(int i =0; i<=lenn; i++){
  150.                     BIT[j][i] = -ll_max;
  151.                 }
  152.             }
  153.            
  154.             for(int i = 0; i<sz(diam); i++){
  155.                 int j = i;
  156.                 int x = gind(-mid + dep[diam[i]] + ignored[diam[i]] -1);
  157.                 best0 = max(best0, dep[diam[j]] + ignored[diam[j]] + S(0, x));
  158.                 best1 = max(best1, dep[diam[j]] + ignored[diam[j]] + S(1, x));
  159.                 best2 = max(best2, -dep[diam[j]] + ignored[diam[j]] + S(2, x));
  160.                 best3 = max(best3, -dep[diam[j]] + ignored[diam[j]] + S(3, x));
  161.                 x = gind(dep[diam[i]] - ignored[diam[i]]);
  162.  
  163.                 U(0, x, dep[diam[i]] + L + ignored[diam[i]] - mid);
  164.                 U(1, x, -dep[diam[i]] + L + ignored[diam[i]] - mid);
  165.                 U(2, x, dep[diam[i]] + L + ignored[diam[i]] - mid);
  166.                 U(3, x, -dep[diam[i]] + L + ignored[diam[i]] - mid);
  167.             }
  168.            
  169.  
  170.             for(int a = 0; a<sz(diam); a++){
  171.                 ll big = min(-best1 + dep[diam[a]], -best3 - dep[diam[a]]);
  172.                 ll small = max(best0 - dep[diam[a]], best2 + dep[diam[a]]);
  173.                 auto it = lower_bound(all(poss), small);
  174.                 if(it == poss.end()) continue;
  175.                 if(small <= *it && big >= *it){
  176.                     yes = 1;
  177.                     break ;
  178.                 }
  179.             }  
  180.  
  181.             mid++;
  182.             if(yes){
  183.                 r = mid;
  184.             }else{
  185.                 l = mid;
  186.             }
  187.         }      
  188.         cout << l << "\n";
  189.     }
  190.    
  191.     return 1;
  192. }
  193.  
  194. signed main(){
  195.   cin.tie(0) -> sync_with_stdio(0);
  196.  
  197.   int T = 1;
  198.   //cin >> T;
  199.   while(solve()){
  200.     }
  201.   return 0;
  202. }
  203.  
  204.  
  205.  
Advertisement
Add Comment
Please, Sign In to add comment