[Merged segment tree] Luogu P3605 [USACO17JAN] Promotion Counting promoted by counting

To a tree of N points, each point having a weight value, find each point in the subtree how many points weights larger than it.

Consider segment tree merger, the discrete weights, weights each point to open a segment tree.

When seeking answers directly in the query tree line weights, similar to the heap segment tree and can be merged.

Note that dynamic segment tree to open the point, do not forget up consolidation.

What's the best memory count, an array of distinguished small.

 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 Tree{int 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

Guess you like

Origin www.cnblogs.com/maximumhanyu/p/11433029.html