This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
int ans;
const int MAXN = 5e5+5;
int sl[MAXN];
int depth[MAXN];
vector<int> ord;
int sr[MAXN];
int p[25][MAXN];
vector<int> v1[MAXN];
int arr[MAXN];
bool coin[MAXN];
int timer;
vector<int> query[MAXN];
void eulertour(int curr){
ord.push_back(curr);
sl[curr] = timer++;
for(int x:v1[curr]){
eulertour(x);
}
sr[curr] = timer;
}
int ancestor(int curr,int level){
for(int i=20;i>=0;i--){
if(level-(1<<i)>=0){
level-=(1<<i);
curr = p[i][curr];
}
}
return curr;
}
int main(){
int n,k;
cin>>n>>k;
for(int i=1;i<n;i++){
cin>>arr[i];
}
for(int i=1;i<=k;i++){
int x;
cin>>x;
coin[x] = true;
}
for(int i=2;i<=n;i++){
p[0][i] = arr[i-1];
depth[i] = depth[p[0][i]]+1;
v1[p[0][i]].push_back(i);
}
for(int i=1;i<=20;i++){
for(int j=1;j<=n;j++){
p[i][j] = p[i-1][p[i-1][j]];
}
}
eulertour(1);
if(coin[1]){
cout<<1<<endl;
return 0;
}
int l =0;
int r = n;
for(int i=2;i<=n;i++){
if(!coin[i]){
continue;
}
int pos = ancestor(i,(depth[i]-1)/2);
query[sl[pos]].push_back(sr[pos]);
}
while(l<=r){
int mid = (l+r)/2;
priority_queue<int,vector<int>, greater<int> > pq;
bool ok = true;
for(int i=0;i<n && ok;i++){
for(int j:query[i]){
pq.push(j);
//timer value(sorts by latest node in the subtree)
}
if(depth[ord[i]]>=mid && !pq.empty()){
int u = pq.top();
pq.pop();
if(u<=i){
ok = false;
}
}
}
if(!pq.empty()){
ok = false;
}
if(ok){
l = mid+1;
ans = mid;
}else{
r = mid-1;
}
}
cout<<ans+1<<endl;
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |