POJ_2182 Lost Cows(线段树的简单应用)

基本思路就是,从后往前读取数字small[i]。在剩余编号集合里(一开始剩余编号集合为全集)查找第small[i]+1个编号,该编号就是对应位置牛的编号。

若直接用数组来做,则每次查找都需要遍历前n个数。而用线段树来做则可以降低为nlogn的复杂度。

事实上感觉可以直接用stl的set来做,直接模拟应该也能不超时得解。

本题主要用来熟悉线段树这个结构。

ac代码如下:

#include<iostream>
#include<cstdio>
#include<cstdio>
using namespace std;
const int maxn=10000;
int small[maxn],ans[maxn];
struct node{
    int lc,rc,len;
};
node tree[maxn*3];//这里一开始数组开小了出现了rte 
void build(int x,int lc,int rc){
    tree[x].lc=lc,tree[x].rc=rc;
    tree[x].len=rc-lc+1;
    if(lc==rc)return ;
    build(x*2,lc,(lc+rc)/2);
    build(x*2+1,(lc+rc)/2+1,rc);
}
int query(int base,int k){
    tree[base].len--;
    if(tree[base].lc==tree[base].rc)return tree[base].lc;
    if(k<=tree[base*2].len){
        return query(base*2,k);
    }
    else{
        return query(base*2+1,k-tree[base*2].len);
    }
}
int main(void){
    int n;
    scanf("%d",&n);
    for(int i=2;i<=n;i++){
        scanf("%d",&small[i]);
    }
    small[1]=0;
    build(1,1,n);
    for(int i=n;i>=1;i--){
        ans[i]=query(1,small[i]+1);
    }
    for(int i=1;i<=n;i++){
        printf("%d\n",ans[i]);
    }
    return 0;
}

 

posted @ 2018-04-06 17:05  KYSpring  阅读(130)  评论(0编辑  收藏  举报