Codeforces Round #612 (Div. 2)
Posted kisekipurin2019
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #612 (Div. 2)相关的知识,希望对你有一定的参考价值。
https://codeforces.com/contest/1287/
A - Angry Students
D - Numbers on Tree
题意:给一棵有根树,规定每个数的子树中有多少个节点的val比根节点的严格小。给这棵树填上任意一种合法的val(每个值都在[1,10^9]且满足上一句话)或报告不存在。
题解:树的这类问题可能都是先往递归的方向考虑,假如是叶子,不用多说之间返回1,否则是中间节点。假如中间节点只有一棵子树,而且子树中的值是相异的,那么随便插进去然后把后面的数往后面挤,得到的也还是值全部相异的树。否则至少有两棵子树,假如他们的值也都是相异的也可以仿照上面解决,可惜搞不得,有可能不存在一个位置刚好满足要求。
这时候很显然的子树之间是没有关系的,可以给一棵子树的值整体提高一个水平,使得得到的值也是相异的,最简单的是加上上一棵子树的最大值(而不一定是size,假如没有进行算不并列的排名的话)。
事实上并不一定需要同一棵子树占据同一段连续的位置,直接全部混在一起算不并列的排名也可以。
int n, root;
int c[2005];
vector<int> G[2005];
vector<pii> vec[2005];
void dfs(int u) {
for(auto &v : G[u]) {
dfs(v);
for(auto &j : vec[v])
vec[u].push_back(j);
}
if(c[u] > vec[u].size()) {
puts("NO");
exit(0);
}
sort(vec[u].begin(), vec[u].end());
for(int i = 0; i < vec[u].size(); ++i)
vec[u][i].first = i + 1;
vec[u].insert(vec[u].begin() + c[u], {c[u] + 1, u});
for(int i = c[u] + 1; i < vec[u].size(); ++i)
++vec[u][i].first;
}
void test_case() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
int p;
scanf("%d%d", &p, &c[i]);
if(p)
G[p].push_back(i);
else
root = i;
}
dfs(root);
for(auto &j : vec[root])
swap(j.first, j.second);
sort(vec[root].begin(), vec[root].end());
puts("YES");
for(auto &j : vec[root])
printf("%d ", j.second);
puts("");
}
注意vector中insert是一个迭代器,而且确实可以在 for auto 中进行交换(应该在遍历中不会改变其他元素的操作都可以吧?)
以上是关于Codeforces Round #612 (Div. 2)的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #612 (Div. 2)
Codeforces Round #612 (Div. 2)