Submission #427259

#TimeUsernameProblemLanguageResultExecution timeMemory
427259model_codeCounterspells (CPSPC17_counterspells)C++17
100 / 100
317 ms37816 KiB
#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 (stderr)

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 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...