Submission #943521

#TimeUsernameProblemLanguageResultExecution timeMemory
943521Zero_OPCat in a tree (BOI17_catinatree)C++14
100 / 100
180 ms54216 KiB
#include<bits/stdc++.h> using namespace std; using int64 = int64_t; #define REP(i, n) for(int i = 0, _n = n; i < _n; ++i) #define REPD(i, n) for(int i = n - 1; i >= 0; --i) #define FOR(i, l, r) for(int i = l, _r = r; i <= _r; ++i) #define FORD(i, r, l) for(int i = r, _l = l; i >= _l; --i) #define left __left #define right __right #define prev __prev #define next __next #define div __div #define pb push_back #define pf push_front #define sz(v) (int)v.size() #define range(v) begin(v), end(v) #define compact(v) v.erase(unique(range(v)), end(v)) #define debug(v) "[" #v " = " << (v) << "]" template<typename T> bool minimize(T& a, const T& b){ if(a > b){ a = b; return true; } return false; } template<typename T> bool maximize(T& a, const T& b){ if(a < b){ a = b; return true; } return false; } template<int dimension, class T> struct vec : public vector<vec<dimension - 1, T>> { static_assert(dimension > 0, "Dimension must be positive !\n"); template<typename... Args> vec(int n = 0, Args... args) : vector<vec<dimension - 1, T>>(n, vec<dimension - 1, T>(args...)) {} }; template<class T> struct vec<1, T> : public vector<T> { vec(int n = 0, T val = T()) : vector<T>(n, val) {} }; void init(void); void process(void); int main(){ ios_base::sync_with_stdio(0); cin.tie(0); #define task "antuvu" if(fopen(task".inp", "r")){ freopen(task".inp", "r", stdin); freopen(task".out", "w", stdout); } int T = 1; //cin >> T; while(T--) { init(); process(); } return 0; } const int MAX = 2e5 + 5; int n, d, timer_dfs, depth[MAX], spt[20][MAX * 2], pos[MAX], par[MAX], count_children[MAX], dp[MAX]; vector<int> adj[MAX]; bool del[MAX]; void init(){ cin >> n >> d; FOR(i, 1, n - 1){ int p; cin >> p; adj[p].pb(i); adj[i].pb(p); } } void pre_dfs(int u, int pre){ spt[0][pos[u] = timer_dfs++] = u; for(int v : adj[u]) if(v != pre){ depth[v] = depth[u] + 1; pre_dfs(v, u); spt[0][timer_dfs++] = u; } } int f(int a, int b){ return depth[a] < depth[b] ? a : b; } void prepareRMQ(){ for(int i = 1; (1 << i) <= timer_dfs; ++i){ for(int j = 0; j + (1 << i) <= timer_dfs; ++j){ spt[i][j] = f(spt[i - 1][j], spt[i - 1][j + (1 << (i - 1))]); } } } int getLCA(int u, int v){ u = pos[u], v = pos[v]; if(u > v) swap(u, v); int step = __lg(v - u + 1); return f(spt[step][u], spt[step][v - (1 << step) + 1]); } int get_distance(int u, int v){ return depth[u] + depth[v] - 2 * depth[getLCA(u, v)]; } int dfs_size(int u, int pre){ count_children[u] = 1; for(int v : adj[u]) if(v != pre and !del[v]){ count_children[u] += dfs_size(v, u); } return count_children[u]; } int find_centroid(int u, int pre, int target){ for(int v : adj[u]) if(v != pre and !del[v] and count_children[v] * 2 > target){ return find_centroid(v, u, target); } return u; } void decompose(int u, int e){ int c = find_centroid(u, e, dfs_size(u, e)); del[c] = true; par[c] = e; for(int v : adj[c]) if(!del[v]) decompose(v, c); } void update(int u){ int v = u; while(v != -1){ minimize(dp[v], get_distance(v, u)); v = par[v]; } } int query(int u){ int ans = INT_MAX, v = u; while(v != -1){ minimize(ans, dp[v] + get_distance(u, v)); v = par[v]; } return ans; } void process(){ pre_dfs(0, -1); prepareRMQ(); decompose(0, -1); memset(dp, 0x3f, sizeof(dp)); vector<pair<int, int>> nodes; REP(i, n){ nodes.pb(make_pair(depth[i], i)); } int ans = 0; sort(range(nodes), greater<pair<int, int>>()); for(auto [x, u] : nodes){ if(query(u) >= d){ ++ans; update(u); } } cout << ans << '\n'; }

Compilation message (stderr)

catinatree.cpp: In function 'void process()':
catinatree.cpp:172:14: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  172 |     for(auto [x, u] : nodes){
      |              ^
catinatree.cpp: In function 'int main()':
catinatree.cpp:60:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   60 |         freopen(task".inp", "r", stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
catinatree.cpp:61:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   61 |         freopen(task".out", "w", stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...