人数统计 树状数组+离散化

来源:互联网 发布:linux top命令详解 编辑:程序博客网 时间:2024/06/07 07:46

NKOJ 4240 人数统计

问题描述

何老板经营着一家大公司,公司总共有n个员工,编号1到n。何老板编号1。

除了何老板外,每个员工有且仅有一个直接上司(呈树状)。每个员工都有一个工作能力值。何老板想知道,对于第i号员工,他的所有下属(包括间接的下属)中,能力值比i强的有多少人?(即统计i为根的子树中,能力值比i大的节点数)

输入格式

第一行,一个整数n,表示公司职员的总数,员工编号1到n。

接下来n行,每行一个整数,其中第i行表示i号员工的能力值。

接下来n-1行,每行一个整数,其中第i行的整数表示编号i+1的员工的直接上司的编号。

输出格式

n行,每行一个整数,其中第i行表示编号为i的员工的下属中,能力比i强的人数。

样例输入

5
80424
85697
66168
70466
95774
1
1
2
3

样例输出

2
0
1
0
0

数据范围

对于约30%的数据,有2<=N<=200
对于100%的数据,有2<=N<=100,000 1<=能力值<=1,000,000,000.


知道NOIP2016 天天爱跑步的思想之后,这道题就比较水了。一边DFS遍历树,一边维护树状数组的题目,还有NKOJ1248 慢慢走。

首先想到大致的框架:首先对于能力值开一个cnt数组。对于节点x,肯定要先搜索它的子树,搜索完之后得到答案,同时用自己的能力值更新cnt数组。那么,肯定要对能力值离散化。修改+维护前缀和,使用树状数组。

那么只剩下一个问题:根据深搜的过程,如果不减,子树以外的其他所有能力值数据仍然保留,这会影响到当前的Ans。显然的想法是对于每个节点开树状数组,然后再合并。但这样显然不行。

事实上,处理方法也很简单。搜索子树之前记录能力值高于它的个数,搜索后做差,改变的值就是Ans。


#include<stdio.h>#include<algorithm>using namespace std;#define MAXN 100005#define MAXM 100005int N,Hash[MAXN],data[MAXN],Size,Ans[MAXN];int tot,en[MAXM],las[MAXN],nex[MAXM];void ADD(int x,int y){    en[++tot]=y;    nex[tot]=las[x];    las[x]=tot;}int C[MAXN];int GetSum(int x){    int i,sum=0;    for(i=x;i;i^=(i&-i))sum+=C[i];    return sum;}void Modify(int x){for(int i=x;i<=N;i+=(i&-i))C[i]++;}void DFS(int x){    int i,y,j=lower_bound(Hash+1,Hash+Size+1,data[x])-Hash,tmp=GetSum(N)-GetSum(j);    for(i=las[x];i;i=nex[i])    {        y=en[i];        DFS(y);    }    Ans[x]=GetSum(N)-GetSum(j)-tmp;    Modify(j);}int main_main(){    int i,x;    scanf("%d",&N);    for(i=1;i<=N;i++)scanf("%d",&data[i]),Hash[i]=data[i];    sort(Hash+1,Hash+N+1);    Size=unique(Hash+1,Hash+N+1)-Hash-1;    for(i=2;i<=N;i++)scanf("%d",&x),ADD(x,i);    DFS(1);    for(i=1;i<=N;i++)printf("%d\n",Ans[i]);}const int main_stack=16;    char my_stack[128<<20];    int main() {  __asm__("movl %%esp, (%%eax);\n"::"a"(my_stack):"memory");      __asm__("movl %%eax, %%esp;\n"::"a"(my_stack+sizeof(my_stack)-main_stack):"%esp");      main_main();      __asm__("movl (%%eax), %%esp;\n"::"a"(my_stack):"%esp");      return 0;    }
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 洛阳燃气卡丢了怎么办 零线火线都带电怎么办 档案里年龄错了怎么办 档案年龄大了怎么办呢 吃菌子致幻了怎么办 野外吃了毒蘑菇怎么办 头顶头发稀少怎么办头顶头发稀 遇见无赖的人该怎么办 扶了老人被讹诈怎么办 遇见碰瓷讹人的怎么办 假机油用了4年怎么办 苹果6手机变砖头怎么办 苹果8升级变砖头怎么办 苹果id锁变砖头怎么办 钥匙断在锁里了怎么办? u型锁忽然打不开怎么办 密码门锁没电了怎么办 智能门锁没电了怎么办 十字锁钥匙丢了怎么办 罐头的拉环断了怎么办 锁坏了 打不开了怎么办 门锁锁不起来了怎么办 卧室门锁舌断了怎么办 锁舌头坏了怎么办自救 门锁斜舌头断了怎么办 锁把手断了半截怎么办 门锁那一块掉了怎么办 qq动态密码忘了怎么办 小三怀孕了原配该怎么办 我当了小三怎么办 被降职后在单位怎么办 领导故意整我该怎么办 小孩怎么教育都不听怎么办 赵本山怎么办的刘涌 起诉离婚被告不出庭怎么办 安装u盘进入系统怎么办 思讯加密狗坏了怎么办 村主任选不出来怎么办 你的id已被停用怎么办 车牌摇号中签后怎么办 北京车卖了指标怎么办