zoukankan      html  css  js  c++  java
  • POJ 2182 Lost Cows (线段树)

    题目大意: 有 n 头牛,编号为 1 - n 乱序排成一列,现已知每头牛前面有多少头牛比它的编号小,从前往后输出每头牛的编号。

    思路: 从后往前推,假如排在最后的一头牛比他编号小的数量为a,那么它的编号必然为a+1。我们把编号为a+1的这头牛删掉,假如排在倒数第二的一头牛比他编号小的数量为b,那么该牛就为删掉最后一头牛后剩余牛中的第b+1头牛,我们可以照此思路下去...
    问题就可以转化为搜索排在第k位的数为多少,我们可以用线段树来实现。

    代码:

      #include<iostream>
      #include<cstdio>
      #include<cstdlib>
      #include<cstring>
      #include<queue>
      #include<algorithm>
      #include<cmath>
      #include<map>
      using namespace std;
      #define INF 0x7fffffff
    
      int ans[10000];
      struct node{
      	      int l,r,value;
      }a[40000];
    
      void buildtree(int i,int l,int r){
          a[i].l = l;
          a[i].r = r;
          a[i].value = 0;
          if(l == r)
              return ;
          int mid = (l + r) / 2 ;
          buildtree(i*2,l,mid);
          buildtree(i*2+1,mid+1,r);
      }
    
      void query(int no,int k,int num){
          a[no].value ++ ;
          if(a[no].l == a[no].r){
    	      ans[k] = a[no].l;
    	      return ;
          }
          if(a[no*2].r - a[no*2].l + 1 - a[no*2].value >= num)
              query(no*2,k,num);
          else{
    	      num -= a[no*2].r - a[no*2].l + 1 - a[no*2].value ;
              query(no*2+1,k,num);
          }
      }
    
      int main(){
          int n,i,j,count[10000];
          cin >> n;
          count[1] = 0 ;
          buildtree(1,1,n);
          for(i=2;i<=n;i++)
              scanf("%d",&count[i]);
          for(j=n;j>0;j--){
       	      query(1,j,count[j]+1);
          }
          for(i=1;i<=n;i++)
              printf("%d
    ",ans[i]);
          return 0;
      }
  • 相关阅读:
    会员管理软件
    正则表达式查找未记录的异常
    网络通信 数据压缩后发送
    SQL 工具系列一
    P5443 [APIO2019]桥梁 [分块+并查集]
    #6499. 「雅礼集训 2018 Day2」颜色 [分块,倍增,bitset]
    CF594D REQ [离线+树状数组,欧拉函数]
    雅礼集训板刷合集
    [HNOI2016]网络 [树链剖分,可删除堆]
    「BZOJ3065」带插入区间K小值 [分块]
  • 原文地址:https://www.cnblogs.com/jxgapyw/p/4767939.html
Copyright © 2011-2022 走看看