• POJ--Lost Cows (线段树)


    题目:http://poj.org/problem?id=2182    http://acm.hdu.edu.cn/showproblem.php?pid=2711

    题意:有N头牛,编号为1--N。 乱序排成一列,已知每头牛前面有多少头牛比它的编号小(从第二头牛开始)。

    现在需要求这个序列中从前到后,每一头牛的编号。

    思路:因为有N头牛,编号为1--N,最后一头牛如果前面有K头牛比它小,那么可以知道最后这头牛的编号为K+1.

    当最后一头牛编号为K+1确定以后,再来看倒数第二头牛,如果这头牛前面有K1头牛比它小,那么这头牛的编号

    必然是剩下N-1头牛中第(K1+1)大的。然后以此类推。。。。

    最开始的线段树为:

    绘图1

    最后一头牛前面有0个比它小,那么这是找第(0+1)大的数。为左下角的(1,1)即1.

    绘图2

    倒数第二头牛前面有1个比它小,那么这头牛是剩下所有牛中第(1+1)大的,为(3,3)即3

    绘图3

    倒数第三头牛前面有2个比它大,那么这头牛是剩下所有牛中第(2+1)大的,为(5,5)即5.

    绘图3

    代码:

    #include<cstdio>
    
    #include<cstring>
    
    #define lson l,m,rt<<1
    
    #define rson m+1,r,rt<<1|1
    
    using namespace std;
    
    const int maxn=8010;
    
    int n,arr[maxn],sum[maxn<<2];
    
    int num[maxn];
    
    void build(int l,int r,int rt)
    
    {
    
    	sum[rt]=r-l+1;
    
    	if(l==r) return;
    
    	int m=(l+r)>>1;
    
    	build(lson);
    
    	build(rson);
    
    }
    
    int query(int p,int l,int r,int rt)
    
    {
    
    	sum[rt]--;
    
    	if(l==r) return l;
    
    	int m=(l+r)>>1;
    
    	if(p<=sum[rt<<1]) return query(p,lson);
    
    	else			  return query(p-sum[rt<<1],rson);
    
    }
    
    int main()
    
    {
    
    	while (~scanf("%d",&n))
    
    	{
    
    		build(1,n,1);
    
    		for(int i=2;i<=n;i++) scanf("%d",&arr[i]);
    
    		arr[1]=0;
    
    		for(int i=n;i>0;i--)
    
    			num[i]=query(arr[i]+1,1,n,1);
    
    		for(int i=1;i<=n;i++)
    
    			printf("%d
    ",num[i]);
    
    	}
    
    	return 0;
    
    }
    
  • 相关阅读:
    js 那些事二 javascript中的闭包理解
    Java单体应用
    Java单体应用
    Java单体应用
    Java单体应用
    Java单体应用
    Java单体应用
    Java入门
    Java入门
    Java入门
  • 原文地址:https://www.cnblogs.com/gt123/p/3705247.html
Copyright © 2020-2023  润新知