• 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;
    }
  • 相关阅读:
    你真的知道async/await的好处嘛, 并且还会用好呢
    Python基本小程序
    猜数字小程序的实现
    Python第一周基本语句学习整理
    Python环境安装与配置
    作业
    Markdown的学习
    创建一个dynamics CRM workflow (四)
    Dynamics CRM 快速获取custom entity
    Dynamics email的subject标题出现 CRM:0000xxxx
  • 原文地址:https://www.cnblogs.com/Zinn/p/9868726.html
Copyright © 2020-2023  润新知