bzoj 4756 Promotion Counting —— 线段树合并

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4756

合并子树的权值线段树;

merge 返回 int 或者是 void 都可以。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define mid ((l+r)>>1)
using namespace std;
int const xn=1e5+5,xm=xn*20;//
int n,p[xn],b[xn],hd[xn],ct,to[xn<<1],nxt[xn<<1];
int cnt,rt[xn],ls[xm],rs[xm],sum[xm],ans[xn],tot;
int rd()
{
  int ret=0,f=1; char ch=getchar();
  while(ch<'0'||ch>'9'){if(ch=='-')f=0; ch=getchar();}
  while(ch>='0'&&ch<='9')ret=(ret<<3)+(ret<<1)+ch-'0',ch=getchar();
  return f?ret:-ret;
}
int gt[20];
void wr(int x)
{
  if(!x){puts("0"); return;}
  if(x<0)putchar('-'),x=-x;
  int t=0;
  while(x)gt[++t]=x%10,x/=10;
  for(int i=t;i;i--)putchar(gt[i]+'0');
  puts("");
}
void add(int x,int y){to[++ct]=y; nxt[ct]=hd[x]; hd[x]=ct;}
void merge(int &x,int y)
{
  if(!x){x=y; return;}
  sum[x]+=sum[y];
  if(ls[y])merge(ls[x],ls[y]);//if
  if(rs[y])merge(rs[x],rs[y]);//if
}
/*
int merge(int x,int y,int l,int r)
{
  if(!x||!y)return x+y;
  sum[x]+=sum[y];
  if(l==r)return x;
  ls[x]=merge(ls[x],ls[y],l,mid);
  rs[x]=merge(rs[x],rs[y],mid+1,r);
  return x;
}
*/
void add(int &x,int l,int r,int pos)
{
  if(!x)x=++cnt; sum[x]++;
  if(l==r)return;
  if(pos<=mid)add(ls[x],l,mid,pos);
  else add(rs[x],mid+1,r,pos);
}
int query(int x,int l,int r,int L,int R)
{
  if(!x)return 0;
  if(l>=L&&r<=R)return sum[x];
  int ret=0;
  if(mid>=L)ret+=query(ls[x],l,mid,L,R);
  if(mid<R)ret+=query(rs[x],mid+1,r,L,R);
  return ret;
}
void dfs(int x)
{
  for(int i=hd[x],u;i;i=nxt[i])
    {
      dfs(u=to[i]);
      //      rt[x]=merge(rt[x],rt[u],1,tot);
      merge(rt[x],rt[u]);
    }
  ans[x]=query(rt[x],1,tot,p[x],tot);
  add(rt[x],1,tot,p[x]);
}
int main()
{
  n=rd();
  for(int i=1;i<=n;i++)p[i]=rd(),b[i]=p[i];
  sort(b+1,b+n+1); tot=unique(b+1,b+n+1)-b-1;
  for(int i=1;i<=n;i++)p[i]=lower_bound(b+1,b+tot+1,p[i])-b;
  for(int i=2,fa;i<=n;i++)fa=rd(),add(fa,i);
  dfs(1);
  for(int i=1;i<=n;i++)wr(ans[i]);
  return 0;
}

 

posted @ 2018-10-29 09:21  Zinn  阅读(178)  评论(0编辑  收藏  举报