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; }