[线段树合并] Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数

Posted maximumhanyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[线段树合并] Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数相关的知识,希望对你有一定的参考价值。

给一棵 N 个点的树,每个点有一个权值,求每个点的子树中有多少个点的权值比它大。

考虑线段树合并,将权值离散化,每个点开一棵权值线段树。

求答案时直接在权值线段树上查询,线段树合并时类似于可并堆。

要注意的是线段树要动态开点,合并时别忘了 up。

内存什么的最好算一下,数组别开小了。

技术图片
 1 #include<bits/stdc++.h>
 2 #define rep(i,a,b) for(register int i=a;i<=b;++i)
 3 #define rpd(i,a,b) for(register int i=a;i>=b;--i)
 4 #define rep1(i,x) for(register int i=head[x];i;i=nxt[i])
 5 typedef long long ll;
 6 const int N=2e5+5;
 7 using namespace std;
 8 inline int read()
 9     int x=0,f=1;char ch=getchar();
10     while(!isdigit(ch))if(ch==-)f=-1;ch=getchar();
11     while(isdigit(ch))x=x*10+ch-0;ch=getchar();
12     return x*f;
13 
14 struct Treeint x,l,r;t[N<<4];
15 int n,tot,cnt;int a[N],b[N],head[N],nxt[N],to[N],rt[N],ans[N];
16 void add(int u,int v)nxt[++tot]=head[u];head[u]=tot;to[tot]=v;
17 void up(int k)t[k].x=t[t[k].l].x+t[t[k].r].x;
18 void build(int &k,int l,int r,int x)
19     k=++cnt;if(l==r)t[k].x=1;return;
20     int mid=l+r>>1;
21     if(mid>=x)build(t[k].l,l,mid,x);
22     else build(t[k].r,mid+1,r,x);
23     up(k);
24 
25 int find(int k,int l,int r,int L,int R)
26     if(L<=l&&r<=R)return t[k].x;
27     if(l>R||r<L)return 0;
28     int mid=l+r>>1;
29     return find(t[k].l,l,mid,L,R)+find(t[k].r,mid+1,r,L,R);
30 
31 int merge(int x,int y)
32     if(!x||!y)return x+y;
33     t[x].x+=t[y].x;
34     t[x].l=merge(t[x].l,t[y].l);
35     t[x].r=merge(t[x].r,t[y].r);
36     up(x);
37     return x;
38 
39 void dfs(int x)
40     rep1(i,x)
41         int p=to[i];dfs(p);
42         rt[x]=merge(rt[x],rt[p]);
43     
44     int k=lower_bound(b+1,b+n+1,a[x])-b;
45     ans[x]=find(rt[x],1,n,k+1,n);
46 
47 int main()
48     n=read();rep(i,1,n)b[i]=a[i]=read();
49     sort(b+1,b+n+1);
50     rep(i,1,n)
51         int k=lower_bound(b+1,b+n+1,a[i])-b;
52         build(rt[i],1,n,k);
53     
54     rep(i,2,n)add(read(),i);dfs(1);
55     rep(i,1,n)printf("%d\n",ans[i]);
56     return 0;
57 
View Code

以上是关于[线段树合并] Luogu P3605 [USACO17JAN]Promotion Counting晋升者计数的主要内容,如果未能解决你的问题,请参考以下文章

P3605 [USACO17JAN]Promotion Counting P (线段树合并)

P3605 [USACO17JAN]Promotion Counting晋升者计数 线段树合并 or 树状数组

题解 P3605 [USACO17JAN]Promotion Counting晋升者计数

P3605 [USACO17JAN]Promotion Counting P (dsu+线段树)

Luogu4556 雨天的尾巴 树上差分线段树合并

luogu3224 永无乡(动态开点,权值线段树合并)