https://www.zybuluo.com/ysner/note/1282069

题面

给一颗带点权的树,求每个点的子树中比该点权值大的点的个数。

  • \(n\leq10^5\)

解析

首先有个很无脑的方法。

用一个权值树状数组维护所有点权(离散化后的)。

每到一个点,询问比该点大的数的个数,然后把这个点权加入树状数组。

dfs回溯以后,再次询问,用这次答案减去上次答案。

这样可以在每个点上直接询问答案。

复杂度\(O(nlog^2n)\)。常数巨小。

然而我做这道题是想入门线段树合并。

其实思想正好相反。

我们不删点权,只把信息从下面合并上来。

对每个点,把它儿子的值域线段树与自己合并。

具体来说是从根节点出发,统计根结点的值,然后合并左儿子右儿子。

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define ll long long
#define re register
#define il inline
#define fp(i,a,b) for(re int i=a;i<=b;i++)
#define fq(i,a,b) for(re int i=a;i>=b;i--)
using namespace std;
const int N=5e5+100,M=1e7;
struct Edge{int to,nxt;}e[N<<1];
int a[N],w[N],n,h[N],cnt,tot,ans[N],rt[M],s[M],ls[M],rs[M],tim;
il void add(re int u,re int v){e[++cnt]=(Edge){v,h[u]};h[u]=cnt;}
il ll gi()
{
re ll x=0,t=1;
re char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') t=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
return x*t;
}
il void Modify(re int &x,re int l,re int r,re int W)
{
if(!x) x=++tim;
++s[x];
if(l==r) return;
re int mid=l+r>>1;
if(W<=mid) return Modify(ls[x],l,mid,W);
return Modify(rs[x],mid+1,r,W);
}
il int Query(re int x,re int l,re int r,re int W)
{
if(!x) return 0;
if(l>=W) return s[x];
re int mid=l+r>>1;
if(W<=mid) return Query(ls[x],l,mid,W)+Query(rs[x],mid+1,r,W);
return Query(rs[x],mid+1,r,W);
}
il int Merge(re int u,re int v)
{
if(!u) return v;if(!v) return u;
re int p=++tim;
s[p]=s[u]+s[v];
ls[p]=Merge(ls[u],ls[v]);
rs[p]=Merge(rs[u],rs[v]);
return p;
}
il void dfs(re int u)
{
for(re int i=h[u];i+1;i=e[i].nxt)
{
re int v=e[i].to;
dfs(v);
rt[u]=Merge(rt[u],rt[v]);
}
ans[u]=Query(rt[u],1,tot,w[u]+1);
Modify(rt[u],1,tot,w[u]);
}
int main()
{
memset(h,-1,sizeof(h));
n=gi();
fp(i,1,n) a[i]=w[i]=gi();
fp(v,2,n)
{
re int u=gi();
add(u,v);
}
sort(a+1,a+1+n);
tot=unique(a+1,a+1+n)-a-1;
fp(i,1,n) w[i]=lower_bound(a+1,a+1+tot,w[i])-a;
dfs(1);
fp(i,1,n) printf("%d\n",ans[i]);
return 0;
}

luogu3605晋升者计数的更多相关文章

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

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

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

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

  3. 树状数组 P3605 [USACO17JAN]Promotion Counting晋升者计数

    P3605 [USACO17JAN]Promotion Counting晋升者计数 题目描述 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训--牛是可怕的管理者! 为了方便,把奶牛从 ...

  4. 【题解】晋升者计数 Promotion Counting [USACO 17 JAN] [P3605]

    [题解]晋升者计数 Promotion Counting [USACO 17 JAN] [P3605] 奶牛们又一次试图创建一家创业公司,还是没有从过去的经验中吸取教训.!牛是可怕的管理者! [题目描 ...

  5. [USACO17JAN] 晋升者计数 dfs序+树状数组

    [USACO17JAN] 晋升者计数 dfs序+树状数组 题面 洛谷P3605 题意:一棵有点权的树,找出树中所有\((u,v)\)的对数,其中\(u,v\)满足\(val(u)\le val(v)\ ...

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

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

  7. 【USACO17JAN】Promotion Counting晋升者计数 线段树+离散化

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

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

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

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

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

随机推荐

  1. js 弹幕效果

    <!DOCTYPE HTML><html><head><meta charset="utf-8"><title>弹幕&l ...

  2. 17Spring前置通知

    1).加入jar包:下载地址 spring-beans-4.1.6.RELEASE.jar commons-logging-1.1.3.jar spring-context-4.1.6.RELEASE ...

  3. Python之机器学习-sklearn生成随机数据

    sklearn-生成随机数据 import numpy as np import pandas as pd import matplotlib.pyplot as plt from matplotli ...

  4. Borrowers

    Description I mean your borrowers of books - those mutilators of collections, spoilers of the symmet ...

  5. 防火墙内设置FileZilla Server注意事项

    开启了Windows下的防火墙,如何设置FileZilla Server 相关选项,能在服务器端只开启21,23端口就可以正常连接使用 方法/步骤   1.       开启windows防火墙,同时 ...

  6. linux 磁盘配额配置

    1. 添加一块新磁盘 ,分区 .格式化 .(mkfs.etx3 /dev/sdc5/) 2.设置开机自动挂载(vi /etc/fstab) 添加磁盘配额支持 (用户配额usrquota.组配额grpq ...

  7. **PHP分步表单提交思路(分页表单提交)

    Q: 我用php做了3张表单 分布在3个页面 想在最后一页 再插入数据库 并且:在插入数据库之前 3个页面 后退 前进 表单的内容会被保留 以便随时更改能实现吗?想过session 感觉内容太多 给服 ...

  8. 什么是单点登录(SSO)

    前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 在我实习之前我就已经在看单点登录的是什么了,但是实习 ...

  9. CSS头像右上角的讨厌红点

    就是这个讨厌的红点,如图: 说明: 1.主要用到position定位: 2.使用border-radius画圆角: 源码: <!DOCTYPE html> <html> < ...

  10. ASPNET Core 部署 Linux — 使用 Jexus Web Server

    第一步 安装.Net Core环境 安装 dotnet 环境参见官方网站 https://www.microsoft.com/net/core. 选择对应的系统版本进行安装.安装完成过后 输入命令查看 ...