zoukankan      html  css  js  c++  java
  • 洛谷P2982 [USACO10FEB]慢下来Slowing down

    题目

    • 题目大意 :给出一棵树,节点有点权,求每个节点的祖先中点权小于该节点的结点的个数 。

    • 思路如下 :

      • 从根节点开始,对树进行深度优先遍历。

      • 当进行到节点 i 时,有:
        •  $ ext{i}$ ​的祖先们 ​$ ext{Father[i]}$ 已经被访问过了,但还没有退出。

        • 其他节点或者已经被访问过并退出了,或者还没有被访问。

      • 那么需要一个数据结构,维护那些已经被访问过了,但还没有退出的点权,支持查询小于特定值的元素的数量

      • 可以使用树状数组或者线段树

    • Code

    • #include <cstdio>
      #include <cstring>
      #define re register
      #define GC getchar()
      #define Clean(X,K) memset(X,K,sizeof(X))
      #define Lowbit(X) (X&(-X))
      int Qread () {
          int X = 0 ;    char C = GC ;
          while (C > '9' || C < '0') C = GC ;
          while (C >='0' && C <='9') {
              X = X * 10 + C - '0' ;
              C = GC ;
          }
          return X ;
      }
      const int Maxn = 100005 ;
      int N ,  P_C[Maxn] , Ans[Maxn] , En = 0 , Head[Maxn] , T[Maxn];
      struct Edge {
          int From_Where , Goto_Where , Next_Edge ;
      };
      Edge E[Maxn * 2] ;
      void Adg (int X , int Y) {
          E[++En].From_Where = X ;
          E[En].Goto_Where = Y ;
          E[En].Next_Edge = Head[X] ;
          Head[X] = En ;
      }
      void Add (int X , int K) {
          while (X <= N) {
              T[X] += K ;
              X += Lowbit(X) ;
          }
      }
      int Ask (int X) {
          int Ans = 0 ;
          while (X > 0) {
              Ans += T[X] ;
              X -= Lowbit(X) ;
          }
          return Ans ;
      }
      void Super_Powerful_DFS (int X , int Lst) {
          Ans[P_C[X]] = Ask (P_C[X]) ;
          //printf ("%d %d %d
      " , X , P_C[X],Ans[P_C[X]]) ;
          Add (P_C[X] , 1) ;
          for (re int i = Head[X] ; i ; i = E[i].Next_Edge ) {
              if (E[i].Goto_Where == Lst) continue ;
              Super_Powerful_DFS ( E[i].Goto_Where , X) ;
          }
          Add (P_C[X] , -1) ;
      }
      int main () {
          //freopen ("P2982.in" , "r" , stdin) ;
          Clean (Ans , 0) , Clean (Head , 0) , Clean (T , 0) , En = 0 ;
          N = Qread () ;
          for (re int i = 1 ; i < N ; ++ i) {
              int X = Qread () , Y = Qread () ;
              Adg (X , Y) , Adg (Y , X) ;
          }
          for (re int i = 1 ; i <= N; ++ i) {
              int X = Qread () ;
              P_C[X] = i ;
          }
          Super_Powerful_DFS ( 1 , -1) ;
          for (re int i = 1 ; i <= N; ++ i) printf ("%d
      " , Ans[i]) ;
          fclose (stdin) ;
          fclose (stdout);
          return 0;
      }
      点击这里学习树状数组

    Thanks !

  • 相关阅读:
    字节跳动--今日头条iOS客户端启动速度优化
    RSA加密
    几种浏览器
    Linux定时任务crontab无法执行
    Python报错ImportError: No Module Named Typing的解决
    微信小程序:A、B两个小程序相互跳转,出现点击A小程序底部导航栏菜单,第一次点击无法跳转B小程序,需要点击第二次才会触发跳转到B小程序
    c# core 生成随机图文验证码
    携程Apollo统一配置管理中心
    WPF程序中嵌入winForm窗体
    sqlserver 转 postgresql
  • 原文地址:https://www.cnblogs.com/bj2002/p/10432150.html
Copyright © 2011-2022 走看看