#include <bits/stdc++.h>
using namespace std;
#define inf 1023456789
#define linf 1023456789123456789ll
#define pii pair<int,int>
#define pipii pair<int, pii >
#define pll pair<long long,long long>
#define vint vector<int>
#define vvint vector<vint >
#define ll long long
#define pdd pair<double, double>
#define DEBUG
#ifdef DEBUG
#define db(x) cerr << #x << " = " << x << endl
#else
#define db(x)
#endif
struct hld_path;
struct node
{
node *parent, *heavy;
vector<node*> sons;
bool heavy_alive;
bool black; //only applies to blocking/head nodes
int subtree, depth;
int black_light;
hld_path* path;
node()
{
parent = NULL;
heavy = NULL;
subtree = 1;
black = true;
depth = 0;
black_light = 0;
heavy_alive = false;
path = NULL;
}
node(node* par)
{
parent = par;
heavy = NULL;
subtree = 1;
black = true;
depth = parent->depth+1;
black_light = 0;
heavy_alive = false;
path = NULL;
parent->sons.push_back(this);
}
};
struct hld_path
{
node* head;
map<int, node*> blocking;
bool get_color(node* n)
{
int d = n->depth;
node *block = head;
map<int, node*>::iterator it = blocking.lower_bound(-d);
if(it != blocking.end())block = it->second;
return (block->black) ^ ((n->depth - block->depth)%2);
}
int counter(node* whom)
{
bool color = get_color(whom);
if(color)
{
return chain(whom);
}
return 0;
}
int counter_light(node* whom)
{
whom->black_light++;
if(whom->black_light == 1 && whom->heavy_alive)
{
whom->heavy->black = get_color(whom->heavy);
blocking[-whom->heavy->depth] = whom->heavy;
}
return counter(whom);
}
int counter_heavy(node* whom)
{
whom->heavy_alive = true;
if(whom->black_light > 0)
{
blocking[-whom->heavy->depth] = whom->heavy;
}
return counter(whom);
}
int uncounter(node* whom)
{
bool black_heavy = 0;
if(whom->heavy_alive) black_heavy = get_color(whom->heavy);
whom->black_light--;
if(whom->black_light == 0 && whom->heavy_alive)
{
blocking.erase(-whom->heavy->depth);
}
if(!black_heavy && (whom->black_light == 0))
{
return chain(whom);
}
return 0;
}
int chain(node* whom)
{
map<int, node*>::iterator it = blocking.lower_bound(-whom->depth);
if(it != blocking.end())
{
it->second->black = !it->second->black;
return whom->depth - it->second->depth + 1;
}
head->black = !head->black;
int res = whom->depth - head->depth + 1;
if(head->parent != NULL)
{
if(head->black)
{
res += head->parent->path->counter_light(head->parent);
}
else
{
res += head->parent->path->uncounter(head->parent);
}
}
return res;
}
hld_path(node* h)
{
head = h;
}
};
void dfs(node* cur)
{
cur->subtree = 1;
for(int i=0; i<cur->sons.size(); i++)
{
dfs(cur->sons[i]);
cur->subtree += cur->sons[i]->subtree;
}
}
void hld(node* n, hld_path* p, vector<hld_path*>& paths)
{
if(p == NULL)
{
p = new hld_path(n);
paths.push_back(p);
}
n->path = p;
pair<int, node*> best(-1, NULL);
for(int i=0; i<n->sons.size(); i++)
{
best = max(best, pair<int, node*>(n->sons[i]->subtree, n->sons[i]));
}
if(best.second != NULL) n->heavy = best.second;
for(int i=0; i<n->sons.size(); i++)
{
if(n->sons[i] == best.second) hld(n->sons[i], p, paths);
else hld(n->sons[i], NULL, paths);
}
}
int main()
{
int n;
scanf("%d", &n);
vector<hld_path*> paths;
vector<node*> nodes;
nodes.push_back(new node);
vint par(n+1, -1);
for(int i=1; i<=n; i++)
{
scanf("%d", &par[i]);
nodes.push_back(new node(nodes[par[i]]));
}
dfs(nodes[0]);
hld(nodes[0], NULL, paths);
for(int i=1; i <= n; i++)
{
int res = 0;
if(nodes[i]->path != nodes[i]->parent->path)
{
res = nodes[i]->parent->path->counter_light(nodes[i]->parent);
}
else
{
res = nodes[i]->path->counter_heavy(nodes[i]->parent);
}
printf("%d\n", res);
}
for(int i=0; i<=n; i++) delete nodes[i];
for(int i=0; i<paths.size(); i++) delete paths[i];
return 0;
}
Compilation message
Main.cpp: In function 'void dfs(node*)':
Main.cpp:153:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
153 | for(int i=0; i<cur->sons.size(); i++)
| ~^~~~~~~~~~~~~~~~~
Main.cpp: In function 'void hld(node*, hld_path*, std::vector<hld_path*>&)':
Main.cpp:169:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
169 | for(int i=0; i<n->sons.size(); i++)
| ~^~~~~~~~~~~~~~~
Main.cpp:174:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<node*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
174 | for(int i=0; i<n->sons.size(); i++)
| ~^~~~~~~~~~~~~~~
Main.cpp: In function 'int main()':
Main.cpp:210:16: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<hld_path*>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
210 | for(int i=0; i<paths.size(); i++) delete paths[i];
| ~^~~~~~~~~~~~~
Main.cpp:184:7: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
184 | scanf("%d", &n);
| ~~~~~^~~~~~~~~~
Main.cpp:191:8: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
191 | scanf("%d", &par[i]);
| ~~~~~^~~~~~~~~~~~~~~
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
332 KB |
Output is correct |
2 |
Correct |
2 ms |
332 KB |
Output is correct |
3 |
Correct |
1 ms |
332 KB |
Output is correct |
4 |
Correct |
1 ms |
460 KB |
Output is correct |
5 |
Correct |
1 ms |
332 KB |
Output is correct |
6 |
Correct |
2 ms |
332 KB |
Output is correct |
7 |
Correct |
1 ms |
332 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
332 KB |
Output is correct |
2 |
Correct |
2 ms |
332 KB |
Output is correct |
3 |
Correct |
1 ms |
332 KB |
Output is correct |
4 |
Correct |
1 ms |
460 KB |
Output is correct |
5 |
Correct |
1 ms |
332 KB |
Output is correct |
6 |
Correct |
2 ms |
332 KB |
Output is correct |
7 |
Correct |
1 ms |
332 KB |
Output is correct |
8 |
Correct |
7 ms |
1740 KB |
Output is correct |
9 |
Correct |
5 ms |
2124 KB |
Output is correct |
10 |
Correct |
5 ms |
1612 KB |
Output is correct |
11 |
Correct |
4 ms |
1868 KB |
Output is correct |
12 |
Correct |
5 ms |
1740 KB |
Output is correct |
13 |
Correct |
7 ms |
1568 KB |
Output is correct |
14 |
Correct |
5 ms |
1356 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
332 KB |
Output is correct |
2 |
Correct |
2 ms |
332 KB |
Output is correct |
3 |
Correct |
1 ms |
332 KB |
Output is correct |
4 |
Correct |
1 ms |
460 KB |
Output is correct |
5 |
Correct |
1 ms |
332 KB |
Output is correct |
6 |
Correct |
2 ms |
332 KB |
Output is correct |
7 |
Correct |
1 ms |
332 KB |
Output is correct |
8 |
Correct |
7 ms |
1740 KB |
Output is correct |
9 |
Correct |
5 ms |
2124 KB |
Output is correct |
10 |
Correct |
5 ms |
1612 KB |
Output is correct |
11 |
Correct |
4 ms |
1868 KB |
Output is correct |
12 |
Correct |
5 ms |
1740 KB |
Output is correct |
13 |
Correct |
7 ms |
1568 KB |
Output is correct |
14 |
Correct |
5 ms |
1356 KB |
Output is correct |
15 |
Correct |
107 ms |
15564 KB |
Output is correct |
16 |
Correct |
58 ms |
18792 KB |
Output is correct |
17 |
Correct |
66 ms |
14684 KB |
Output is correct |
18 |
Correct |
40 ms |
17296 KB |
Output is correct |
19 |
Correct |
60 ms |
14904 KB |
Output is correct |
20 |
Correct |
68 ms |
12396 KB |
Output is correct |
21 |
Correct |
54 ms |
14648 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
308 ms |
32148 KB |
Output is correct |
2 |
Correct |
123 ms |
32352 KB |
Output is correct |
3 |
Correct |
66 ms |
28312 KB |
Output is correct |
4 |
Correct |
118 ms |
29336 KB |
Output is correct |
# |
Verdict |
Execution time |
Memory |
Grader output |
1 |
Correct |
1 ms |
332 KB |
Output is correct |
2 |
Correct |
2 ms |
332 KB |
Output is correct |
3 |
Correct |
1 ms |
332 KB |
Output is correct |
4 |
Correct |
1 ms |
460 KB |
Output is correct |
5 |
Correct |
1 ms |
332 KB |
Output is correct |
6 |
Correct |
2 ms |
332 KB |
Output is correct |
7 |
Correct |
1 ms |
332 KB |
Output is correct |
8 |
Correct |
7 ms |
1740 KB |
Output is correct |
9 |
Correct |
5 ms |
2124 KB |
Output is correct |
10 |
Correct |
5 ms |
1612 KB |
Output is correct |
11 |
Correct |
4 ms |
1868 KB |
Output is correct |
12 |
Correct |
5 ms |
1740 KB |
Output is correct |
13 |
Correct |
7 ms |
1568 KB |
Output is correct |
14 |
Correct |
5 ms |
1356 KB |
Output is correct |
15 |
Correct |
107 ms |
15564 KB |
Output is correct |
16 |
Correct |
58 ms |
18792 KB |
Output is correct |
17 |
Correct |
66 ms |
14684 KB |
Output is correct |
18 |
Correct |
40 ms |
17296 KB |
Output is correct |
19 |
Correct |
60 ms |
14904 KB |
Output is correct |
20 |
Correct |
68 ms |
12396 KB |
Output is correct |
21 |
Correct |
54 ms |
14648 KB |
Output is correct |
22 |
Correct |
308 ms |
32148 KB |
Output is correct |
23 |
Correct |
123 ms |
32352 KB |
Output is correct |
24 |
Correct |
66 ms |
28312 KB |
Output is correct |
25 |
Correct |
118 ms |
29336 KB |
Output is correct |
26 |
Correct |
317 ms |
32072 KB |
Output is correct |
27 |
Correct |
125 ms |
37816 KB |
Output is correct |
28 |
Correct |
153 ms |
32980 KB |
Output is correct |
29 |
Correct |
88 ms |
34340 KB |
Output is correct |
30 |
Correct |
95 ms |
29544 KB |
Output is correct |
31 |
Correct |
154 ms |
25364 KB |
Output is correct |
32 |
Correct |
123 ms |
32076 KB |
Output is correct |