POJ 2182 Lost Cows (线段树)

题目链接

这题需要逆向思维一下吧,两个地方注意下就行了。一个就是从后往前推,先把最后位置的确认了是第几个,再确认倒数第二个。

另一个就是想到怎样用线段树,一开始我想大概也跟前几篇博客那种按先后次序添加进来,但想了想,这题应该是按我们确认位置的次序,把已经确认的给踢出去,所以用线段树来维护L到R区间,依然未被确认位置的个数,在初始化的时候,由于肯定是全都未确认,所以可以用(r - l +1)来表示各区间的个数。

最后就是从后往前,一个个查询到底是哪个数(即叶子节点)就行。

说几句做这些题的感触:无论是树状数组还是线段树,我们只要理解了这两种数据结构,通常建树,修改,查询,都是比较简单的(至少现在看来),重点是我们怎样用这两种结构来维护数据,往往一个题目看上去跟这两种结构毫无关系,但仔细想想之后(发现更多是逆向思考),确实可以找出能用他们来维护数据的办法,我觉得这是相比于DP稍微好一点的地方(DP。。不多说,都是泪)

代码还是比较简单易懂的:

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Scanner;

public class Main{
	static Scanner sc = new Scanner(System.in);
	static int n;
	static BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
	static int [] sum;
	static int [] ipt;
	static int [] opt;
	static void init(int l, int r, int rt) {
		sum[rt] = r - l + 1;
		if(l == r) return;
		int m = (l+r) >> 1;
		init(l, m, rt<<1);
		init(m+1, r, rt<<1|1);
	}
	static int query(int rt, int l, int r, int val) {
		sum[rt]--;
		if(l == r)return l;
		int m = (l+r)>>1;
		if(sum[rt<<1] >= val)
			return query(rt<<1, l, m, val);
		else
			return query(rt<<1|1, m+1, r, val - sum[rt<<1]);
	}
	public static void main(String[] args) throws  IOException {
		while(sc.hasNext()) {
			n = sc.nextInt();
			sum = new int[4*n+1];
			ipt = new int[n+1];
			opt = new int[n+1];
			init(1,n,1);
			for(int i = 2; i <= n; i++) {
				ipt[i] = sc.nextInt();
			}
			for(int i = n; i >= 1; i--) {
				opt[i] = query(1,1,n,ipt[i] +1);
			}
			for(int i = 1; i <= n; i++) {
				System.out.println(opt[i]);
			}
		}
		System.exit(0);
	}
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值