pku_2182_Lost Cows

一道线段树求排列顺序的简单题.

题目大意:

给一个数N表示有N头牛,农夫先牵出一头(当然不知道是第几头),接下来N-1行表示他把剩下个数中的第i头牛牵了出来.位置从0开始.

问题是问每头牛在队列中的位置.

例如题目样例中:

1,2,1,0

因为从0开始,为了便于理解,我们全部加1:

2,3,2,1

牛的编号:   1 2 3 4 5

第一次牵出第2头,是编号2

1 3 4 5

第二次牵出剩下的第2头,是编号4

1 3 5

第三次牵出剩下的第3头,是编号5

1 3

第四次牵出剩下的第2头,是编号3

1

第五次.....


解题思想和注意事项:

由上例可以看出,只要对牵出的顺序逆序操作,就可模拟反向的操作过程.对于样例中有五头牛的序列

1,1,1,1,1

从最后一位数据开始,将每次牵出的第i头补回当前序列剩余的第i个位置即可.

逆向序列: 1,2,3,2,?

第一回 i=1: 0,1,1,1,1

第二回 i=2: 0,1,0,1,1

第三回 i=3: 0,1,0,1,0

第四回 i=2: 0,1,0,0,0

第五回 最后一回: 编号为,仅剩的位置


由此可以归纳为解求剩余位置中第N位的问题,要求快速查找和更新,我选择的数据结构为线段树.

建树的函数为标准模板建树,每个叶子初值为1,每个结点统计区间和.

更新函数用来求剩余位置中的第i个位置.具体做法将记录的值和左右子树比较,因为给出的位置一定是合理的可找到的,若大于左子树,则减去左子树值递归到右子树.

最后还需要询问函数,询问最后剩下那个位置编号是什么.


源代码:

#include <myhead.h>

const int N=8010;
#define ROOT 1,n,1
int n;
int data[N],result[N];
int seg[N<<2];

inline void pushUp(int rt)
{
	seg[rt]=seg[LL(rt)]+seg[RR(rt)];
}

void build(int l,int r,int rt)
{
	if(l==r) {
		seg[rt]=1;
		return ;
	}
	int mid=MID(l,r);
	build(LSON);
	build(RSON);
	pushUp(rt);
}

void init()
{
	build(ROOT);
	memset(result,0,sizeof(result));
	for(int i=1;i<n;++i)
		scanf("%d",&data[i]);
}

void updata(int p,int x,int l,int r,int rt)
{
	if(l==r) {
		result[x]=l;
		seg[rt]=0;
		return ;
	}
	int mid=MID(l,r);
	if(seg[LL(rt)]>=p) updata(p,x,LSON);
	else			   updata(p-seg[LL(rt)],x,RSON);
	pushUp(rt);
}

void query(int l,int r,int rt)
{
	if(l==r) {
		result[0]=l;
		return ;
	}
	int mid=MID(l,r);
	if(seg[LL(rt)]) query(LSON);
	else			query(RSON);
}

void work()
{
	for(int i=n-1;i>0;--i)
		updata(data[i]+1,i,ROOT);
	query(ROOT);
	for(int i=0;i<n;++i)
		printf("%d\n",result[i]);
}

int main()
{
	while(~scanf("%d",&n)) {
		init();
		work();
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值