이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include <bits/stdc++.h>
using namespace std;
const int nmax = 70000;
int n, k;
vector<pair<int,int>> G[nmax + 5];
int w[nmax + 5], lvl[nmax + 5], Max[nmax + 5], eMax[nmax + 5];
bool sel[nmax + 5];
int sz = 0;
multiset<pair<long long,int>> s;
long long rez[nmax + 5];
priority_queue<pair<int,int>> *sd[nmax + 5];
vector<pair<int,int>> lv[nmax + 5];
vector<pair<int,int>> lst;
void parcurg(priority_queue<pair<int,int>> *h, bool del = false)
{
while(!h->empty())
{
lst.push_back(h->top());
h->pop();
}
if(!del)
{
for(auto it : lst)
{
h->push(it);
}
}
}
priority_queue<pair<int,int>> *red(priority_queue<pair<int,int>> *h, int val, int nod, int mul)
{
int cnt = 0;
while(!h->empty() && k - ((h -> top().first) - lvl[nod]) < val)
{
cnt += (h -> top().second);
rez[nod] += 1LL * (h -> top().second) * mul;
h->pop();
}
if(!cnt)
{
return h;
}
h->push({lvl[nod], cnt});
return h;
}
void get_w(int nod, int dad = 0)
{
w[nod] = 1;
Max[nod] = 0;
for(auto it : G[nod])
{
if(it.first == dad || sel[it.first])
{
continue;
}
get_w(it.first, nod);
if(w[it.first] > w[Max[nod]])
{
Max[nod] = it.first;
eMax[nod] = it.second;
}
w[nod] += w[it.first];
}
}
int get_centroid(int nod, int dad = 0)
{
int Max = sz - w[nod];
for(auto it : G[nod])
{
if(it.first == dad || sel[it.first])
{
continue;
}
Max = max(Max, w[it.first]);
int centroid = get_centroid(it.first, nod);
if(centroid)
{
return centroid;
}
}
if(Max <= sz / 2)
{
return nod;
}
return 0;
}
void debug(vector<pair<int,int>> c)
{
for(auto it : c)
{
cerr<<it.first<<' '<<it.second<<'\n';
}
cerr<<'\n';
}
void dfs(int nod, int dad = 0, int mul = -1, int path = 1)
{
if(Max[nod] == 0)
{
sd[path] -> push({lvl[nod], 1});
return;
}
lvl[Max[nod]] = lvl[nod] + eMax[nod];
if(mul == -1)
{
dfs(Max[nod], nod, sz - w[Max[nod]], path);
sd[path] = red(sd[path], eMax[nod], Max[nod], sz - w[Max[nod]]);
lst.clear();
parcurg(sd[path]);
lv[Max[nod]] = lst;
}
else
{
dfs(Max[nod], nod, mul, path);
sd[path] = red(sd[path], eMax[nod], Max[nod], mul);
}
sd[path] -> push({lvl[nod], 1});
for(auto it : G[nod])
{
if(it.first == dad || sel[it.first] || it.first == Max[nod])
{
continue;
}
lvl[it.first] = lvl[nod] + it.second;
if(mul == -1)
{
dfs(it.first, nod, sz - w[it.first], path + 1);
sd[path + 1] = red(sd[path + 1], it.second, it.first, sz - w[it.first]);
lst.clear();
parcurg(sd[path + 1], true);
lv[it.first] = lst;
}
else
{
dfs(it.first, nod, mul, path + 1);
sd[path + 1] = red(sd[path + 1], it.second, it.first, mul);
lst.clear();
parcurg(sd[path + 1], true);
}
for(auto er : lst)
{
sd[path] -> push(er);
}
}
}
void calc(int nod, long long dif, int edge, int dad)
{
vector<pair<long long,int>> rem;
int cnt = 0;
while(!s.empty())
{
auto it = s.begin();
if(it -> first >= dif)
{
break;
}
cnt += it -> second;
rem.push_back(*it);
s.erase(it);
}
if(cnt)
{
s.insert({k + dif - edge, cnt});
}
rez[dad] += 1LL * cnt * w[nod];
for(auto it : G[nod])
{
if(it.first == dad || sel[it.first])
{
continue;
}
calc(it.first, dif + it.second, it.second, nod);
}
for(auto it : rem)
{
s.insert(it);
}
if(cnt)
{
auto er = s.lower_bound({k + dif - edge, cnt});
s.erase(er);
}
}
void solve(int nod)
{
get_w(nod);
sz = w[nod];
int centroid = get_centroid(nod);
get_w(centroid);
sel[centroid] = true;
lvl[centroid] = 0;
dfs(centroid);
lst.clear();
s.clear();
parcurg(sd[1], true);
for(auto it : lst)
{
s.insert({k - it.first, it.second});
}
for(auto son : G[centroid])
{
if(sel[son.first])
{
continue;
}
for(auto it : lv[son.first])
{
auto er = s.lower_bound({k - it.first, it.second});
s.erase(er);
}
calc(son.first, son.second, son.second, centroid);
for(auto it : lv[son.first])
{
s.insert({k - it.first, it.second});
}
}
for(auto it : G[centroid])
{
if(sel[it.first])
{
continue;
}
solve(it.first);
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
#ifdef home
freopen("nr.in","r",stdin);
freopen("nr.out","w",stdout);
#endif // home
cin>>n>>k;
for(int i=1;i<=n;i++)
{
sd[i] = new priority_queue<pair<int,int>>();
}
for(int i=1; i<n; i++)
{
int x, y, c;
cin>>x>>y>>c;
++x;
++y;
G[x].push_back({y, c});
G[y].push_back({x, c});
}
solve(1);
for(int i=1; i<=n; i++)
{
cout<<rez[i]<<'\n';
}
return 0;
}
# | 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... |