Submission #144999

#TimeUsernameProblemLanguageResultExecution timeMemory
144999brcodeTax Evasion (LMIO19_mokesciai)C++14
100 / 100
428 ms67408 KiB
#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 timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...