• 洛谷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 !

  • 相关阅读:
    bootstrap中nav-fixed-top和nav-static-top的区别
    bootstrap aria
    pixi学习总结
    我的代码需要随时备份,并且保证最新版与别人协同开发?Git与Github一起用啊
    自己本地的代码,如何随时备份?随时找回上个备份?版本控制工具Git啊
    自己的代码,如何跟别人协同开发?用GitHub啊
    函数放到onload里面,在html里面执行函数会报错-----作用域和闭包相关问题
    使用CSS实现空心的向上向下的箭头
    两个input放一行不能对齐
    发现一个h5网站,爱果果
  • 原文地址:https://www.cnblogs.com/bj2002/p/10432150.html
Copyright © 2020-2023  润新知