Submission #362255

#TimeUsernameProblemLanguageResultExecution timeMemory
362255alextodoranCat in a tree (BOI17_catinatree)C++17
100 / 100
304 ms171756 KiB
/** ____ ____ ____ ____ ____ ||a |||t |||o |||d |||o || ||__|||__|||__|||__|||__|| |/__\|/__\|/__\|/__\|/__\| **/ #include <bits/stdc++.h> using namespace std; typedef long long ll; const int N_MAX = 200002; const int BUFFER_SIZE = 100000; char buffer[BUFFER_SIZE]; int bpos = BUFFER_SIZE - 1; char read_char () { bpos++; if(bpos == BUFFER_SIZE) { fread(buffer, sizeof(char), BUFFER_SIZE, stdin); bpos = 0; } return buffer[bpos]; } bool isDigit[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int read_int () { char c; while(!isDigit[c = read_char()]); int ans = 0; while(isDigit[c]) { ans = ans * 10 + c - '0'; c = read_char(); } return ans; } int n, maxd; int parent[N_MAX]; vector <int> sons[N_MAX]; int depth[N_MAX]; deque <int> dp[N_MAX]; int vsum[N_MAX]; int vmax[N_MAX]; void solve (int u) { if(sons[u].empty() == true) { dp[u].push_back(1); return; } for(int v : sons[u]) { solve(v); depth[u] = max(depth[u], depth[v] + 1); } int secondDepth = -1; bool firstDepth = false; for(int v : sons[u]) if(depth[v] + 1 == depth[u] && firstDepth == false) firstDepth = true; else secondDepth = max(secondDepth, depth[v]); for(int d = 0; d <= min(maxd / 2, secondDepth + 1); d++) vsum[d] = vmax[d] = 0; for(int v : sons[u]) { int lim = min({maxd / 2, depth[v] + 1, secondDepth + 1}); for(int d = 1; d <= lim; d++) { int val = 0; if(maxd - d - 1 <= depth[v]) val = dp[v][maxd - d - 1]; vsum[d] += val; vmax[d] = max(vmax[d], dp[v][d - 1] - val); } } int deepSon = -1; for(int v : sons[u]) if(deepSon == -1 || depth[v] > depth[deepSon]) deepSon = v; int sum = 1; for(int v : sons[u]) if(maxd - 1 <= depth[v]) sum += dp[v][maxd - 1]; swap(dp[u], dp[deepSon]); dp[u].push_front(sum); for(int v : sons[u]) if(v != deepSon) { int lim = min(maxd - 1, depth[v] + 1); for(int d = (maxd + 1) / 2; d <= lim; d++) dp[u][d] += dp[v][d - 1]; } for(int d = 1; d <= min(maxd / 2, secondDepth + 1); d++) dp[u][d] = vsum[d] + vmax[d]; for(int d = min(maxd - 2, secondDepth + 1); d >= 0; d--) dp[u][d] = max(dp[u][d], dp[u][d + 1]); } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); n = read_int(); maxd = read_int(); for(int i = 2; i <= n; i++) parent[i] = read_int() + 1; for(int i = 2; i <= n; i++) sons[parent[i]].push_back(i); solve(1); cout << dp[1][0] << "\n"; return 0; }

Compilation message (stderr)

catinatree.cpp: In function 'int read_int()':
catinatree.cpp:54:22: warning: array subscript has type 'char' [-Wchar-subscripts]
   54 |     while(!isDigit[c = read_char()]);
      |                    ~~^~~~~~~~~~~~~
catinatree.cpp:56:19: warning: array subscript has type 'char' [-Wchar-subscripts]
   56 |     while(isDigit[c])
      |                   ^
catinatree.cpp: In function 'char read_char()':
catinatree.cpp:27:14: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)', declared with attribute warn_unused_result [-Wunused-result]
   27 |         fread(buffer, sizeof(char), BUFFER_SIZE, stdin);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...