이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
using namespace std;
const int BLOCK = 500;
const int MAXN = 5e5;
const int Q = 1e6 + 3;
const int MAXL = 20;
template<class T> using matrix = vector<vector<T>>;
int n, d, depths[MAXN + 5], block[MAXN + 5], first[MAXN + 5], last[MAXN + 5], sparse[MAXN + 5][MAXL], lg2[2 * MAXN + 5], T = 1, euler[2 * MAXN + 5], used[MAXN + 5];
priority_queue<pair<int, int>> pq; vector<int> vq;
matrix<int> G;
int get_int();
ll get_ll();
void dfs_depths(int u, int p, int d){
depths[u] = d;
euler[T] = u; last[u] = first[u] = T ++;
for(auto v : G[u]){
if(v == p) continue;
dfs_depths(v, u, d + 1);
euler[T] = u; last[u] = T ++;
}
}
void init(){
lg2[1] = 0;
for(int i = 2; i <= T; i ++){
lg2[i] = lg2[i / 2] + 1;
}
for(int i = 1; i < T; i ++){
sparse[i][0] = euler[i];
}
for(int l = 1; l <= MAXL; l ++){
for(int i = 1; i + (1 << l) - 1 <= T; i ++){
int u = sparse[i][l - 1];
int v = sparse[i + (1 << (l - 1))][l - 1];
sparse[i][l] = (depths[u] < depths[v] ? u : v);
}
}
}
int get_lca(int u, int v){
if(first[u] > first[v]) swap(u, v);
u = first[u]; v = last[v];
int j = lg2[v - u + 1];
int a = sparse[u][j];
int b = sparse[v - (1 << j) + 1][j];
return (depths[a] > depths[b] ? b : a);
}
int get_dist(int u, int v){
int c = get_lca(u, v);
return depths[u] + depths[v] - 2 * depths[c];
}
void bfs(){
for(int i = 0; i < n; i ++){
used[i] = block[i] = 0;
}
queue<int> qq;
for(auto x : vq){
block[x] = d;
qq.push(x);
}
while(!qq.empty()){
auto u = qq.front(); qq.pop();
if(!block[u]) continue;
used[u] = true;
for(auto v : G[u]){
block[v] = max(block[v], block[u] - 1);
if(!used[v]) qq.push(v);
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
// cin >> n >> d;
n = get_int();
d = get_int();
G.resize(n + 1);
for(int i = 1; i < n; i ++){
int p; p = get_int(); // cin >> p;
G[p].push_back(i);
G[i].push_back(p);
}
dfs_depths(0, 0, 0);
init();
for(int i = 0; i < n; i ++){
pq.push({depths[i], i});
}
int ans = 0;
queue<int> q;
vector<int> cache;
while(!pq.empty()){
auto [_, u] = pq.top(); pq.pop();
bool good = (block[u] ? false : true);
for(auto x : cache){
good &= (get_dist(u, x) >= d);
}
if(good){
++ ans;
cache.push_back(u);
}
if(cache.size() == BLOCK){
for(auto x : cache) vq.push_back(x);
cache.clear();
bfs();
}
}
cout << ans << endl;
}
int ptr = Q - 1;
char buff[Q];
void next_char(){ if(++ptr == Q) fread(buff, 1, Q, stdin), ptr = 0; }
int get_int(){
int ret = 0;
for(; buff[ptr] < '0' || '9' < buff[ptr]; next_char());
for(; '0' <= buff[ptr] && buff[ptr] <= '9'; next_char())
ret = 10 * ret + buff[ptr] - '0';
return ret;
}
ll get_ll(){
ll ret = 0;
for(; buff[ptr] < '0' || '9' < buff[ptr]; next_char());
for(; '0' <= buff[ptr] && buff[ptr] <= '9'; next_char())
ret = 10 * ret + buff[ptr] - '0';
return ret;
}
컴파일 시 표준 에러 (stderr) 메시지
catinatree.cpp: In function 'int main()':
catinatree.cpp:102:8: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
102 | auto [_, u] = pq.top(); pq.pop();
| ^
catinatree.cpp: In function 'void next_char()':
catinatree.cpp:123:39: warning: ignoring return value of 'size_t fread(void*, size_t, size_t, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
123 | void next_char(){ if(++ptr == Q) fread(buff, 1, Q, stdin), ptr = 0; }
| ~~~~~^~~~~~~~~~~~~~~~~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |