이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#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 = 1e16;
const ll BASE = 137;
const int szBL = 350;
struct edges {
int u, v, w;
};
int n;
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(INF, 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 = min(INF, 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("c");
// 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
4
1 0 74
2 0 100
3 0 8
4 2 81
*/
컴파일 시 표준 에러 (stderr) 메시지
roads.cpp: In member function 'void sub6::Segment_Tree::update(int, int, int, int, long long int)':
roads.cpp:93:25: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
93 | 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 time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |