hihocoder1994 deciduous tree with the DFS and prefix + + bipartite

DFS find the time to delete nodes, the time is actually deleted subtrees longest chain, and a play time stamp for each point, and then find the corresponding node each time point the number deleted, the time stamp for the required 1-max_time and a prefix, then find and m-half from the nearest day

#include<iostream>
#include<algorithm>
#include<string.h>
#include<stdio.h>
#include<vector>
#include<map>
using namespace std;
const int maxx = 2e5+6;
const int INF = 0x3f3f3f3f;
vector<int>v;
int ver[maxx],edge[maxx],Next[maxx],head[maxx];
int sz[maxx];
int vis[maxx];
int cnt[maxx];
int pre[maxx];
int tot,n,mx,m;
void add(int u,int v){
  ver[++tot]=v;Next[tot]=head[u];head[u]=tot;
  ver[++tot]=u;Next[tot]=head[v];head[v]=tot;
}
int dfs(int u,int fa){
   for (int i=head[u];i;i=Next[i]){
      int v=ver[i];
      if (v==fa)continue;
      vis[u]=max(vis[u],dfs(v,u));
   }
   return vis[u]+1;
}
int main(){
  int q;
  int uu,vv,st;
  scanf("%d%d",&n,&q);
  tot=0;
  for (int i=1;i<=n;i++){
    scanf("%d",&uu);
    sz[uu]++;
    sz[i]++;
    if(uu==0){
      st=i;
      continue;
    }
    add(uu,i);
  }
  for (int i=1;i<=n;i++){
    if(sz[i]==1 && i!=st){
        vis[i]=1;
    }
  }
  dfs(st,0);
  mx=0;
  for (int i=1;i<=n;i++){
     cnt[vis[i]]++;
     mx=max(mx,vis[i]);
  }
  for (int i=1;i<=mx;i++){
    pre[i]=pre[i-1]+cnt[i];
  }
  pre[0]=0;
  v.push_back(n);
  for (int i=1;i<=mx;i++){
    v.push_back(n-pre[i]);
  }
  reverse(v.begin(),v.end());
  int ans;
  while(q--){
   scanf("%d",&m);
   int pos=lower_bound(v.begin(),v.end(),m)-v.begin();
  // cout<<"ss"<<pos<<endl;
   if (pos==v.size()){
      printf("1\n");
   }else if (pos==0){
      printf("%d\n",v.size());
   }else{
      if (abs(v[pos]-m)<=abs(v[pos-1]-m)){
         printf("%d\n",v.size()-pos);
      }else {
         printf("%d\n",v.size()-pos+1);
      }
   }
  }
  return 0;
}

 

Guess you like

Origin www.cnblogs.com/bluefly-hrbust/p/11601260.html