线段树合并
洛谷P3605 [USACO17JAN] Promotion Counting P
#include<bits/stdc++.h>
using namespace std;
int cnt,a[100010],b[100010],fa[100010],rt[100010],ans[100010],tot;
struct jade
{
int lc,rc,num;
}t[4000010];
int n;
vector<int> q[100010];
void pushup(int pos)
{
t[pos].num=t[t[pos].lc].num+t[t[pos].rc].num;
}
int insert(int pos,int l,int r,int v)
{
if(!pos)
{
tot++;
pos=tot;
}
if(l==r)
{
t[pos].num++;
return pos;
}
int mid=(l+r)>>1;
if(v<=mid)
{
t[pos].lc=insert(t[pos].lc,l,mid,v);
}
else
{
t[pos].rc=insert(t[pos].rc,mid+1,r,v);
}
pushup(pos);
return pos;
}
int merge(int x,int y,int l,int r)
{
if(!x)
{
return y;
}
if(!y)
{
return x;
}
if(l==r)
{
t[x].num+=t[y].num;
}
int mid=(l+r)>>1;
t[x].lc=merge(t[x].lc,t[y].lc,l,mid);
t[x].rc=merge(t[x].rc,t[y].rc,mid+1,r);
pushup(x);
return x;
}
int ask(int pos,int l,int r,int x,int y)
{
if(x<=l&&r<=y)
{
return t[pos].num;
}
int mid=(l+r)>>1;
int res=0;
if(x<=mid)
{
res+=ask(t[pos].lc,l,mid,x,y);
}
if(y>mid)
{
res+=ask(t[pos].rc,mid+1,r,x,y);
}
return res;
}
void dfs(int x)
{
for(int i=0;i<q[x].size();i++)
{
int to=q[x][i];
if(to==fa[x])
{
continue;
}
dfs(to);
rt[x]=merge(rt[x],rt[to],1,cnt);
}
ans[x]=ask(rt[x],1,cnt,a[x]+1,cnt);
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
b[i]=a[i];
}
sort(b+1,b+1+n);
cnt=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+1+n,a[i])-b;
rt[i]=insert(rt[i],1,cnt,a[i]);
}
for(int i=2;i<=n;i++)
{
int x;
cin>>x;
fa[i]=x;
q[x].push_back(i);
q[i].push_back(x);
}
dfs(1);
for(int i=1;i<=n;i++)
{
cout<<ans[i]<<endl;
}
return 0;
}
以下是签名
${\scr {jade }}$ ${\scr {seek }}$
本文来自博客园,作者:BIxuan—玉寻,转载请注明原文链接:https://www.cnblogs.com/zhangyuxun100219/p/18986447

浙公网安备 33010602011771号