Submission #1089818

#TimeUsernameProblemLanguageResultExecution timeMemory
1089818underwaterkillerwhaleRoad Closures (APIO21_roads)C++17
31 / 100
311 ms90208 KiB
#include <bits/stdc++.h> #define ll long long #define pii pair<int,int> #define pll pair<ll,ll> #define rep(i,m,n) for(int i=(m); i<=(n); i++) #define reb(i,m,n) for(int i=(m); i>=(n); i--) #define iter(id, v) for(auto id : v) #define fs first #define se second #define MP make_pair #define pb push_back #define bit(msk, i) ((msk >> i) & 1) #define SZ(v) (ll)v.size() #define ALL(v) v.begin(),v.end() using namespace std; mt19937_64 rd(chrono :: steady_clock :: now ().time_since_epoch().count()); ll Rand (ll l, ll r) { return uniform_int_distribution<ll> (l, r) (rd); } const int N = 2e5 + 7; const int Mod = 1e9 + 2022; ///loonf mod sai const ll INF = 1e14; const ll BASE = 137; const int szBL = 350; struct edges { int u, v, w; }; int n; vector<int> edges; vector<pii> ke[N]; namespace sub4 { int Wp[N]; ll dp[N][2]; void dfs (int u, int p, int X) { vector<ll> vec; ll Tot = 0; iter (&id, ke[u]) { int v, w; tie(v, w) = id; if (v != p) { Wp[v] = w; dfs(v, u, X); Tot += dp[v][0]; vec.pb({-dp[v][0] + dp[v][1]}); } } int m = SZ(ke[u]); dp[u][0] = Tot; dp[u][1] = Tot + Wp[u]; rep (i, 0, SZ(vec) - 1) { if (m - i - 1 >= X) dp[u][0] += vec[i]; else dp[u][0] += min(0LL, vec[i]); if (m - i - 2 >= X) dp[u][1] += vec[i]; else dp[u][1] += min(0LL, vec[i]); } if (m - SZ(vec) > X) dp[u][0] = INF; } vector<ll> solution() { vector<ll> Ans; rep (X, 0, n - 1) { dfs(1, 0, X); Ans.pb(dp[1][0]); // cout << dp[1][0] <<" "; } return Ans; } } namespace sub6 { vector<int> ke2[N]; vector<int> vertices[N]; int ein[N], high[N], par[N][25], deg[N], Wp[N]; ll dp[N][2]; struct Segment_Tree { int m; vector<ll> st, cnt, zip; void update (int id, int l, int r, int pos, ll val) { if (l > pos || r < pos) return; if (l == r) { st[id] += val * zip[l - 1]; cnt[id] += val; return; } int mid = l + r >> 1; update (id << 1, l, mid, pos, val); update (id << 1 | 1, mid + 1, r, pos, val); st[id] = st[id << 1] + st[id << 1 | 1]; cnt[id] = cnt[id << 1] + cnt[id << 1 | 1]; } ll walk (int id, int l, int r, int K) { if (cnt[id] < K) return INF; if (l == r) return zip[l - 1] * K; int mid = l + r >> 1; if (cnt[id << 1] <= K) return st[id << 1] + walk (id << 1 | 1, mid + 1, r, K - cnt[id << 1]); else return walk (id << 1, l, mid, K); } void init (vector<ll> &com) { zip = com; sort (ALL(zip)); zip.resize(m = unique(ALL(zip)) - zip.begin()); st.assign(4 * m, 0); cnt.assign(4 * m, 0); iter (&id, com) update(id, 1); } void update (int W, int val) { int pos = lower_bound(ALL(zip), W) - zip.begin() + 1; update (1, 1, m, pos, val); } ll get (int K) { if (m == 0) return K == 0 ? 0 : INF; return walk (1, 1, m, K); } }ST[N]; void pdfs (int u, int p) { static int time_dfs = 0; high[u] = high[p] + 1; ein[u] = ++time_dfs; par[u][0] = p; rep (i, 1, 20) par[u][i] = par[par[u][i - 1]][i - 1]; vector<ll> vec; iter (&id, ke[u]) { int v, w; tie(v, w) = id; if (v != p) { Wp[v] = w; vec.pb(Wp[v]); pdfs(v, u); } } ST[u].init(vec); } int LCA (int u, int v) { if (high[u] > high[v]) swap(u, v); rep (i, 0, 20) if (bit(high[v] - high[u], i)) v = par[v][i]; if (v == u) return v; reb (i, 20, 0) if (par[u][i] != par[v][i]) v = par[v][i], u = par[u][i]; return par[u][0]; } int Near (int u, int anc) { rep (i, 0, 20) if (bit(high[u] - high[anc] - 1, i)) u = par[u][i]; return u; } void dfs (int u, int X) { iter (&v, ke2[u]) { dfs(v, X); } if (deg[u] <= X) { dp[u][0] = 0; iter (&v, ke2[u]) { dp[u][0] += min(dp[v][0], dp[v][1]); } dp[u][1] = dp[u][0] + Wp[u]; // cout << u<<" "<<dp[u][0] <<" "<<dp[u][1] <<"\n"; return; } vector<ll> vec; ll Tot = 0; iter (&v, ke2[u]) { Tot += dp[v][0]; vec.pb({-dp[v][0] + dp[v][1]}); ST[u].update(Wp[v], -1); } sort (ALL(vec)); dp[u][0] = dp[u][1] = INF; ll pref = 0; rep (i, 0, SZ(vec)) { ll delta1 = ST[u].get(max(0, deg[u] - i - X)), delta2 = ST[u].get(max(0, deg[u] - i - 1 - X)); dp[u][0] = min(dp[u][0], Tot + pref + delta1); dp[u][1] = min(dp[u][1], Tot + Wp[u] + pref + delta2); if (i < SZ(vec)) pref += vec[i]; } if (X == 0 && u != 1) dp[u][0] = INF; // cout << u<<" "<<dp[u][0] <<" "<<dp[u][1] <<"\n"; iter (&v, ke2[u]) { ST[u].update(Wp[v], 1); } } void build_virtual (vector<int> &ver) { ver.pb(1); sort (ALL(ver), [] (int A, int B) { return ein[A] < ein[B]; }); int m = SZ(ver); rep (i, 0, m - 2) ver.pb(LCA(ver[i], ver[i + 1])); sort (ALL(ver), [] (int A, int B) { return ein[A] < ein[B]; }); ver.resize(unique(ALL(ver)) - ver.begin()); m = SZ(ver); rep (i, 0, m - 2) { int u = LCA(ver[i], ver[i + 1]), v = ver[i + 1], k = Near (v, u); ke2[u].pb(k); if (k != v) ke2[k].pb(v); ver.pb(k); } } vector<ll> solution() { pdfs(1, 0); rep (u, 1, n) { deg[u] = SZ(ke[u]); vertices[deg[u]].pb(u); } reb (i, n, 0) { iter (id, vertices[i + 1]) vertices[i].pb(id); } vector<ll> Ans; rep (X, 0, n - 1) { static vector<int> ver; iter (&v, ver) vector<int> ().swap(ke2[v]); ver.clear(); iter (&u, vertices[X]) ver.pb(u); build_virtual(ver); // cout << X<<":\n"; dfs(1, X); // cout << dp[1][0] <<" "; Ans.pb(dp[1][0]); } return Ans; } } vector<ll> minimum_closure_costs (int _n, vector<int> _u, vector<int> _v, vector<int> _w) { n = _n; rep (i, 1, n - 1) { int u = _u[i - 1], v = _v[i - 1], w = _w[i - 1]; ++u; ++v; ke[u].pb({v, w}); ke[v].pb({u, w}); } // if (n <= 2000) return sub4 :: solution(); // else return sub6 :: solution(); } void solution() { cin >> n; rep (i, 1, n - 1) { int u, v, w; cin >> u >> v >> w; ++u; ++v; ke[u].pb({v, w}); ke[v].pb({u, w}); } // if (n <= 2000) return sub4 :: solution(); // else sub6 :: solution(); } //#define file(name) freopen(name".inp","r",stdin); \ //freopen(name".out","w",stdout); //int main () { //// file("noel"); // ios_base :: sync_with_stdio(false); cin.tie(0); cout.tie(0); // int num_Test = 1; //// cin >> num_Test; // while (num_Test--) // solution(); //} /* no bug +8 chu y break hay return se lam hong logic xet transition cua i va i + 1 construct ket qua 5 0 1 1 0 2 4 0 3 3 2 4 2 */

Compilation message (stderr)

roads.cpp:278:1: warning: multi-line comment [-Wcomment]
  278 | //#define file(name) freopen(name".inp","r",stdin); \
      | ^
roads.cpp: In member function 'void sub6::Segment_Tree::update(int, int, int, int, long long int)':
roads.cpp:94:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   94 |             int mid = l + r >> 1;
      |                       ~~^~~
roads.cpp: In member function 'long long int sub6::Segment_Tree::walk(int, int, int, int)':
roads.cpp:104:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  104 |             int mid = l + r >> 1;
      |                       ~~^~~
roads.cpp: In function 'int sub6::LCA(int, int)':
roads.cpp:152:29: warning: suggest parentheses around '-' inside '>>' [-Wparentheses]
  152 |             if (bit(high[v] - high[u], i)) v = par[v][i];
      |                     ~~~~~~~~^~~~~~~~~
roads.cpp:12:27: note: in definition of macro 'bit'
   12 | #define bit(msk, i)     ((msk >> i) & 1)
      |                           ^~~
roads.cpp: In function 'int sub6::Near(int, int)':
roads.cpp:161:41: warning: suggest parentheses around '-' inside '>>' [-Wparentheses]
  161 |             if (bit(high[u] - high[anc] - 1, i)) u = par[u][i];
      |                     ~~~~~~~~~~~~~~~~~~~~^~~
roads.cpp:12:27: note: in definition of macro 'bit'
   12 | #define bit(msk, i)     ((msk >> i) & 1)
      |                           ^~~
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...