P3605 [USACO17JAN]Promotion Counting晋升者计数

题目描述

奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者!

为了方便,把奶牛从 1 \(\cdots\) N(1 \(\leq\) N \(\leq\) 100, 000) 编号,把公司组织成一棵树,1 号奶牛作为总裁(这棵树的根节点)。除了总裁以外的每头奶牛都有一个单独的上司(它在树上的 “双亲结点”)。所有的第 i 头牛都有一个不同的能力指数 p(i),描述了她对其工作的擅长程度。如果奶牛 i 是奶牛 j 的祖先节点(例如,上司的上司的上司),那么我们我们把奶牛 j 叫做 i 的下属。

不幸地是,奶牛们发现经常发生一个上司比她的一些下属能力低的情况,在这种情况下,上司应当考虑晋升她的一些下属。你的任务是帮助奶牛弄清楚这是什么时候发生的。简而言之,对于公司的中的每一头奶牛 i,请计算其下属 j 的数量满足 p(j) > p(i)。

输入输出格式

输入格式:输入的第一行包括一个整数 N。

接下来的 N行包括奶牛们的能力指数 p(1)⋯p(N). 保证所有数互不相同,在区间 1⋯109 之间。

接下来的 N−1 行描述了奶牛2⋯N 的上司(双亲节点)的编号。再次提醒,1 号奶牛作为总裁,没有上司。

输出格式:输出包括 N 行。输出的第 i 行应当给出有多少奶牛 i 的下属比奶牛i能力高。

一句话题意:给出一个树形结构,求每个节点其子树中节点权值比他大的个数。

如果树退化成链的话,那就是裸的求逆序对数,上树状数组。

接下来考虑树的情况,因为要求该节点与其子树中节点的大小关系,所以不难想到搞出一个DFS序,然后将DFS序看成序列,对上面的点每一次进行区间求和即可。

考虑我们现在要求节点i的答案,那么在树状数组里的一定是比i要大的,既然知道了这个顺序,那么就将每个节点按权值大小排序,每一次查询在DFS序里该点的dfn到dfn+size-1即可查询整个区间,用右端点减去左端点减一的位置的答案,即可得出此时的答案,再将现在这个点放进树状数组里,表示个数加一,去接着为权值更小的点的答案做贡献。

code:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int wx=100017;
inline int read(){
int sum=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
sum=(sum<<1)+(sum<<3)+ch-'0';
ch=getchar();
}
return sum*f;
}
struct e{
int nxt,to;
}edge[wx*2];
struct node{
int v,id;
friend bool operator < (const node& a,const node& b){
return a.v>b.v;
}
}a[wx];
int head[wx],size[wx],dfn[wx],ans[wx],sum[wx];
int n,num,tot,x;
void add(int from,int to){
edge[++num].nxt=head[from];
edge[num].to=to;
head[from]=num;
}
void dfs(int u){
dfn[u]=++tot;size[u]=1;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
dfs(v);
size[u]+=size[v];
}
}
void update(int pos,long long k)
{
for(int i=pos;i<=n;i+=(i&-i)){
sum[i]+=k;
}
}
int query(int x){
long long re=0;
for(int i=x;i>=1;i-=(i&-i)){
re+=sum[i];
}
return re;
}
int main(){
n=read();
for(int i=1;i<=n;i++)a[i].v=read(),a[i].id=i;
for(int i=2;i<=n;i++){
x=read();add(x,i);
}
dfs(1);
sort(a+1,a+1+n);
for(int i=1;i<=n;i++){
ans[a[i].id]=query(dfn[a[i].id]+size[a[i].id]-1)-query(dfn[a[i].id]-1);
update(dfn[a[i].id],1);
}
for(int i=1;i<=n;i++)printf("%d\n",ans[i]);
return 0;
}

树状数组 P3605 [USACO17JAN]Promotion Counting晋升者计数的更多相关文章

  1. 线段树合并 || 树状数组 || 离散化 || BZOJ 4756: [Usaco2017 Jan]Promotion Counting || Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

    题面:P3605 [USACO17JAN]Promotion Counting晋升者计数 题解:这是一道万能题,树状数组 || 主席树 || 线段树合并 || 莫队套分块 || 线段树 都可以写..记 ...

  2. 洛谷 P3605 [USACO17JAN]Promotion Counting晋升者计数

    题目描述 The cows have once again tried to form a startup company, failing to remember from past experie ...

  3. 洛谷P3605 [USACO17JAN] Promotion Counting 晋升者计数 [线段树合并]

    题目传送门 Promotion Counting 题目描述 The cows have once again tried to form a startup company, failing to r ...

  4. luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

    题目链接 luogu 思路 可以说是线段树合并的练手题目吧 也没啥说的,就是dfs,然后合并... 看代码吧 错误 和写主席树错的差不多 都是变量写错.... 代码 #include <bits ...

  5. P3605 [USACO17JAN]Promotion Counting晋升者计数

    思路 线段树合并的板子.. 和子节点合并之后在值域线段树上查询即可 代码 #include <cstdio> #include <algorithm> #include < ...

  6. Luogu3605 [USACO17JAN]Promotion Counting晋升者计数

    Luogu3605 [USACO17JAN]Promotion Counting晋升者计数 给一棵 \(n\) 个点的树,点 \(i\) 有一个权值 \(a_i\) .对于每个 \(i\) ,求 \( ...

  7. [USACO17JAN] Promotion Counting晋升者计数 (树状数组+dfs)

    题目大意:给你一棵树,求以某节点为根的子树中,权值大于该节点权值的节点数 本题考查dfs的性质 离散+树状数组求逆序对 先离散 我们发现,求逆序对时,某节点的兄弟节点会干扰答案 所以,我们在递推时统计 ...

  8. [USACO17JAN]Promotion Counting晋升者计数

    题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 1 \cdots N(1 \leq N \leq 100, 000)1⋯N(1≤N ...

  9. BZOJ4756 [USACO17JAN]Promotion Counting晋升者计数

    Description The cows have once again tried to form a startup company, failing to remember from past ...

随机推荐

  1. PowerDesigner中添加约束

    唯一约束 唯一约束与创建唯一索引基本上是一回事,因为在创建唯一约束的时候,系统会创建对应的一个唯一索引,通过唯一索引来实现约束.不过唯一约束更直观的表达了对应列的唯一性,使得对应索引的目的更加清晰,所 ...

  2. DAY13-前端之JavaScript

    JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中),后将其改名ScriptEase(客 ...

  3. c语言中argc和argv

    main函数的参数,解释如下: argc:命令行总的参数的个数,即argv中元素的格式. *argv[ ]:字符串数组,用来存放指向你的字符串参数的指针数组,每一个元素指向一个参数. argv[0]: ...

  4. 安装Oracle 11.2.0.3 Client Win 32-bit

    第一步:安装Oracle 11.2 32-bit数据库1.双击setup文件,进入安装界面 2.选择跳过升级选项 3.设置oracle安装根目录 4.确认选项,没有问题点击“安装” 第二步:创建数据库

  5. 数据库开源框架ormlite

    今天听说了ORM框架ORMLITE,特地去了解了一下. 该框架可以使用注解方式来生成数据库表,还封装了常用的数据库操作. 类似J2EE的HIBERNATE框架对数据库的处理. 省去了书写建表语句的麻烦 ...

  6. 从公交塞车,看C#多线程问题(转)

    好久没写博客了,可能是因为最近工作太过于压抑的原因吧!有点颓废了.... 而且公司距离住处要坐公交将近40--50分钟(各个原因,纠结中ing...),提前一个半小时起床,居然还能迟到!因为距离公司前 ...

  7. jmeter CSV Data数据中带有逗号解决方法

    今天用jmeter做性能测试,由于参数的数据中含有逗号,一直失败,尝试了几次终于成功,先写下经验 首先看设置 E:\apache-jmeter-2.12\bin\litaojunzb.csv文件格式如 ...

  8. 算法Sedgewick第四版-第1章基础-010一检查括号是否成对出现

    /****************************************************************************** * Compilation: javac ...

  9. 2用java代码实现冒泡排序算法(转载)

    import java.util.Scanner; public class Maopao { public static void main(String[] args) { System.out. ...

  10. 触摸屏、X11去掉鼠标

    cursor disable in X11 Last updated 8 years ago 摘自:http://www.noah.org/wiki/cursor_disable_in_X11 Whe ...