zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    SOUI开发者论坛
    第二十五篇:在SOUI中做事件分发处理
    第二十四篇:导出SOUI对象到LUA脚本
    第二十三篇:在SOUI中使用LUA脚本开发界面
    第四章:为妹子镶上璀璨的珠宝
    第三章:为妹子重塑婀娜身段
    第二章:美丽的幻想灰飞烟灭
    第一章:描绘妹子的靓影
    拥抱ARM妹子 序章!ARM妹子~~ 哥我来啦!
    一个比较方便的关闭进程函数
  • 原文地址:https://www.cnblogs.com/Zinn/p/9868726.html
Copyright © 2011-2022 走看看