zoukankan      html  css  js  c++  java
  • 青出于蓝胜于蓝 dfs+树状数组

    武当派一共有 nn 人,门派内 nn 人按照武功高低进行排名,武功最高的人排名第 11,次高的人排名第 22,... 武功最低的人排名第 nn。现在我们用武功的排名来给每个人标号,除了祖师爷,每个人都有一个师父,每个人可能有多个徒弟。

    我们知道,武当派人才辈出,连祖师爷的武功都只能排行到 pp。也就是说徒弟的武功是可能超过师父的,所谓的青出于蓝胜于蓝。

    请你帮忙计算每个人的所有子弟(包括徒弟的徒弟,徒弟的徒弟的徒弟....)中,有多少人的武功超过了他自己。

    输入格式

    输入第一行两个整数 n, p $(1 le n le 100000, 1 le p le n)$

    接下来 n-1n1 行,每行输入两个整数 u, v$(1 le u, v le n)$,表示 uu 和 vv 之间存在师徒关系。

    输出格式

    输出一行 nn 个整数,第 ii 个整数表示武功排行为 ii 的人的子弟有多少人超过了他。

    行末不要输出多余的空格。

    样例输入

    10 5
    5 3
    5 8
    3 4
    3 1
    2 1
    6 7
    8 7
    9 8
    8 10

    样例输出

    0 0 2 0 4 0 1 2 0 0

    挺好的一个题,就记录下了。

    算出每个点有多少个儿子节点,然后求相应的区间与l逆序对的数量。

     1 #include <bits/stdc++.h>
     2 #define lowbit(x) (-x&(x))
     3 using namespace std;
     4 const int N = 1e5+10;
     5 vector<int> vs[N];
     6 typedef pair<int,int> P;
     7 vector<P> vs1[N];
     8 int a[N], d[N], sum[N], dp[N][2], res;
     9 
    10 int dfs(int v, int f) {
    11     a[++res] = v;
    12     int sum = 0;
    13     for(auto u : vs[v]) {
    14         if(u == f) continue;
    15         d[u] = dfs(u, v);
    16         sum += d[u]+1;
    17     }
    18     return sum;
    19 }
    20 void add(int x, int y) {
    21     while(x < N) {
    22         sum[x] += y;
    23         x += lowbit(x);
    24     }
    25 }
    26 int query(int x) {
    27     int s = 0;
    28     while(x > 0) {
    29         s += sum[x];
    30         x -= lowbit(x);
    31     }
    32     return s;
    33 }
    34 int main() {
    35     int n, p, u, v;
    36     scanf("%d%d", &n, &p);
    37     for(int i = 1; i < n; i ++) {
    38         scanf("%d%d", &u, &v);
    39         vs[u].push_back(v);
    40         vs[v].push_back(u);
    41     }
    42     d[p] = dfs(p, -1);
    43     // for(int i = 1; i <= n; i ++) printf("%d ",a[i]);printf("
    ");
    44     // for(int i = 1; i <= n; i ++) printf("%d ",d[a[i]]);printf("
    ");
    45     for(int i = 1; i <= n; i ++) {
    46         vs1[i+d[a[i]]].push_back(P(a[i],i));
    47     }
    48     for(int i = n; i >= 1; i --) {
    49         for(auto p : vs1[i]) {
    50             dp[p.first][0] = query(p.first);
    51         }
    52         dp[a[i]][1] = query(a[i]);
    53         // printf("%d
    ",i);
    54         add(a[i], 1);
    55     }
    56     for(int i = 1; i <= n; i ++) printf("%d%c",dp[i][1]-dp[i][0]," 
    "[i==n]);
    57     return 0;
    58 }
  • 相关阅读:
    Visual Studio使用阿里云Code Git服务器的常见问题
    使用Quartz.net来执行定时任务
    DirectorySearcher.Filter 属性(转)
    angular2的ElementRef在组件中获取不到
    angular2 ngfor循环
    angular2 日期格式化
    angular2在模板中使用属性引发Cannot read property 'xxx' of undefined
    Java ConcurrentHashMap存入引用对象时也是线程安全的
    FtpHelper实现ftp服务器文件读写操作(C#)
    Window服务项目脚手架
  • 原文地址:https://www.cnblogs.com/xingkongyihao/p/9852779.html
Copyright © 2011-2022 走看看