zoukankan      html  css  js  c++  java
  • Luogu3605 [USACO17JAN]Promotion Counting晋升者计数

    Luogu3605 [USACO17JAN]Promotion Counting晋升者计数

    给一棵 (n) 个点的树,点 (i) 有一个权值 (a_i) 。对于每个 (i) ,求 (displaystylesum_{jin subtree(i)}{[a_i<a_j]})

    (nleq10^5, fa_i<i)

    树状数组


    树上逆序对?一眼线段树合并、、、空间没毛病、、

    回想求序列逆序对的过程,发现在树上做时只需减去树状数组中以往的贡献,于是便可以愉快地树状数组搞了

    时间复杂度 (O(nlog n)) ,空间复杂度 (O(n))

    #include <bits/stdc++.h>
    using namespace std;
    
    #define nc getchar()
    const int maxn = 1e5 + 10;
    int n, a[maxn], dat[maxn], c[maxn], ans[maxn]; vector <int> e[maxn];
    
    inline int read() {
      int x = 0; char c = nc;
      while (c < 48) c = nc;
      while (c > 47) x = x * 10 + c - 48, c = nc;
      return x;
    }
    
    void upd(int pos) {
      for (; pos <= n; pos += pos & -pos) {
        c[pos]++;
      }
    }
    
    int query(int pos) {
      int res = 0;
      for (; pos; pos &= pos - 1) {
        res += c[pos];
      }
      return res;
    }
    
    void dfs(int u) {
      int lst = query(n) - query(a[u]); upd(a[u]);
      for (int v : e[u]) dfs(v);
      ans[u] = query(n) - query(a[u]) - lst;
    }
    
    int main() {
      n = read();
      for (int i = 1; i <= n; i++) {
        dat[i] = a[i] = read();
      }
      for (int i = 2; i <= n; i++) {
        e[read()].push_back(i);
      }
      sort(dat + 1, dat + n + 1);
      for (int i = 1; i <= n; i++) {
        a[i] = lower_bound(dat + 1, dat + n + 1, a[i]) - dat;
      }
      dfs(1);
      for (int i = 1; i <= n; i++) {
        printf("%d
    ", ans[i]);
      }
      return 0;
    }
    
  • 相关阅读:
    Vue数组循环
    vue使用swiper6分页器踩坑
    Vue基础语法(四)
    Vue安装jquery
    Vue基础语法(三)
    Too Rich(贪心加搜索)
    ZOJ Anagrams by Stack(堆栈中的搜索)
    最长子序列和(分治法实现)
    幸运数字(数位dp)
    蜥蜴和地下室(深搜)
  • 原文地址:https://www.cnblogs.com/Juanzhang/p/10363928.html
Copyright © 2011-2022 走看看