zoukankan      html  css  js  c++  java
  • poj2182 Lost Cows

     1 #include<stdio.h>
     2 #define N 8010
     3 struct node{
     4     int l,r;
     5     int len;//len用来存放某一段数据的个数 
     6 }tree[N<<1];
     7 int s[N],result[N];
     8 void build(int l,int r,int i)
     9 {
    10     tree[i].l=l;
    11     tree[i].r=r;
    12     tree[i].len=r-l+1; 
    13     if(l==r) return;
    14     int mid=(l+r)>>1;
    15     build(l,mid,i<<1);
    16     build(mid+1,r,(i<<1)+1);
    17 }
    18 int order(int s,int i)
    19 {
    20     tree[i].len--;//每进行一次取出操作,结点个数都要减一 
    21     if(tree[i].l==tree[i].r) return tree[i].l;//树的l就是牛的编号 
    22     if(s<=tree[i<<1].len) return order(s,i<<1);//假如要找的第s名的s<左子树的左边界,则在左子树上查找 
    23     else return order(s-tree[i<<1].len,(i<<1)+1);//否则在右子树上查找,注意在右子树查找时,是查找第(s-tree[i<<1])个节点的编号 
    24 }
    25 int main()
    26 {
    27     int i,n;
    28     while(~scanf("%d",&n)){
    29         build(1,n,1);
    30         for(i=1;i<n;++i)
    31             scanf("%d",&s[i]);
    32         for(i=n-1;i>0;--i)
    33             result[i]=order(s[i]+1,1);
    34         result[0]=order(1,1);//最后一个就剩一个了,也就是第一个 
    35         for(i=0;i<n;++i)
    36             printf("%d\n",result[i]);
    37     }
    38     return 0;
    39 }

    搜索排在第n位的数是几时可用线段树实现,对于一个线段树中的所代表的线段[a,b],结点中的数值纪录[a,b]中有多少人,记为len,所以对于一个在剩余数字队列中排在第n位,看这个人是在一个结点的左子树中还是右子树中,

    判断的依据是用左子树的r和n比较,

    如果r>=n说明在左子树形成的队列中有足够的数字使他排在第n位,于是递归找左子树。

    如果r <n说明在左子树形成的队列中没有足够的数字使他排在第n位,所以他在右子树的第n-r位,于是递归在右子树中找;

    当然每找到一个数字,要将所有的祖先结点信息改变,即len--;

  • 相关阅读:
    多项式的一些操作
    AtCoder Grand Contest 036E
    THUWC2017 随机二分图
    THUWC2017 在美妙的数学王国中畅游
    SDOI2017 切树游戏
    ZJOI2017 树状数组
    HNOI2015 接水果
    LOJ6503 Magic
    Charles 抓去app接口的使用
    mysql 字符串类型和数字对比的坑
  • 原文地址:https://www.cnblogs.com/shihuajie/p/2631908.html
Copyright © 2011-2022 走看看