zoukankan      html  css  js  c++  java
  • hihocoder1994 树与落叶 DFS+前缀和+二分

    DFS找到节点删除的时间,删除的时间其实就是子树的最长链,然后给每个点打一个时间戳,然后求每个时间点对应删除的节点的个数,对于1-max_time时间戳求一个前缀和,然后二分找到和m距离最近的那一天

    #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
    ");
       }else if (pos==0){
          printf("%d
    ",v.size());
       }else{
          if (abs(v[pos]-m)<=abs(v[pos-1]-m)){
             printf("%d
    ",v.size()-pos);
          }else {
             printf("%d
    ",v.size()-pos+1);
          }
       }
      }
      return 0;
    }
  • 相关阅读:
    [LeetCode]Sort List
    [LeetCode]Single Number II
    合并两个排序的列表
    翻转链表
    链表中倒数第k个结点
    调整数组顺序使奇数位于偶数前面
    数值的整数次方
    二进制中1的个数
    矩形覆盖
    变态跳台阶
  • 原文地址:https://www.cnblogs.com/bluefly-hrbust/p/11601260.html
Copyright © 2011-2022 走看看