Poj(2182)——Lost Cows(线段树)

Description

N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood ‘watering hole‘ and drank a few too many beers before dinner. When it was time to line up for their evening meal, they did
not line up in the required ascending numerical order of their brands.

Regrettably, FJ does not have a way to sort them. Furthermore, he‘s not very good at observing problems. Instead of writing down each cow‘s brand, he determined a rather silly statistic: For each cow in line, he knows the number of cows that precede that cow
in line that do, in fact, have smaller brands than that cow.

Given this data, tell FJ the exact ordering of the cows.

Input

* Line 1: A single integer, N

* Lines 2..N: These N-1 lines describe the number of cows that precede a given cow in line and have brands smaller than that cow. Of course, no cows precede the first cow in line, so she is not listed. Line 2 of the input describes the number of preceding cows
whose brands are smaller than the cow in slot #2; line 3 describes the number of preceding cows whose brands are smaller than the cow in slot #3; and so on.

Output

* Lines 1..N: Each of the N lines of output tells the brand of a cow in line. Line #1 of the output tells the brand of the first cow in line; line 2 tells the brand of the second cow; and so on.

最近学了一下线段树,把基本题目都做了一下,但是一直都没有时间来总结一下,所以现在抽空总结了一下。

这道题的题意大致是:

有N头奶牛,编号为1~N,乱序排成一列,现在已知每头牛前面有多少头牛比它的编号小,求排队后从前往后数,每头牛的编号。

注意因为第一头牛前面肯定只有0头牛比它的编号小,那么题目这里没有给出,所以我们要自己加上去。

一开始没想到要怎么用线段树,看了一下题解后,然后懂了。

首先我们从后往前扫描,然后遇到数字a,就说明它是原先剩余序列中第a+1个数,找到该编号后删除,然后继续重复上述的操作。那么哪里用到了线段树呢?找的过程要用到线段树,看一个区间内未被删除的数字个数能否满足使当前要找的数成为第a+1个,能则递归左子树,否则递归右子树,那么叶子节点的值就是其初始编号。

#include<stdio.h>
#include<string.h>
#define maxn 10000
int small[maxn],ans[maxn];	//ans是用来存储结果的;
struct node{
	int lc,rc,len;
}s[4*maxn];
void build(int root,int lc,int rc){
	s[root].lc=lc;
	s[root].rc=rc;
	s[root].len=rc-lc+1;
	if(lc==rc) return ;
	build(2*root,lc,(lc+rc)/2);
	build(2*root+1,(lc+rc)/2+1,rc);
}
int query(int root,int k){
	s[root].len--;
	if(s[root].lc==s[root].rc)return s[root].lc;
	else if(s[2*root].len>=k) return query(root*2,k);
	else return query(root*2+1,k-s[root*2].len);<span style="white-space:pre">		</span>//询问右边的区间时,要减去左边的区间长度。
}
int main(){
	int n;
	scanf("%d",&n);
	for(int i=2;i<=n;i++) scanf("%d",&small[i]);
	small[1]=0;<span style="white-space:pre">			</span>//注意这里,这是代表是第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]);
}
时间: 2024-10-31 12:42:21

Poj(2182)——Lost Cows(线段树)的相关文章

POJ 2182 Lost Cows.(线段树)

~~~~ 数据太水,暴力无压力,不过还是用线段树写了下,表现了楼主对线段树的无限热爱之情. ~~~~ 题目连接:http://poj.org/problem?id=2182 大致题意;牛牛因XXXXXX原因乱序成一排,现已知每头牛前面有多少头牛比它的编号小(第一头牛前面没有当然就不列粗来了),求每头牛的编号. 思路:从后往前扫描,遇到a,则说明它是剩余序列的第a+1头牛. ~~~~ 暴力代码:(157ms) #include<cstdio> #include<algorithm>

poj 2182 Lost Cows(线段树经典题)

题目链接:http://poj.org/problem?id=2182 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9152   Accepted: 5879 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, th

poj 2182 Lost Cows (线段树)

 Lost Cows Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8838   Accepted: 5657 Description N (2 <= N <= 8,000) cows have unique brands in the range 1..N. In a spectacular display of poor judgment, they visited the neighborhood 'wate

POJ 2481 Cows (线段树)

Cows 题目:http://poj.org/problem?id=2481 题意:有N头牛,每只牛有一个值[S,E],如果对于牛i和牛j来说,它们的值满足下面的条件则证明牛i比牛j强壮:Si <=Sjand Ej <= Ei and Ei - Si > Ej - Sj.现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮. 思路:将牛按照S从小到大排序,S相同按照E从大到小排序,这就保证了排在后面的牛一定不比前面的牛强壮.再按照E值(离散化后)建立一颗线段树(这里最值只有1e5,所

POJ 3264-Balanced Lineup(线段树:单点更新+区间查询)

Balanced Lineup Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 34522   Accepted: 16224 Case Time Limit: 2000MS Description For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer Joh

POJ训练计划2777_Count Color(线段树/成段更新/区间染色)

解题报告 题意: 对线段染色,询问线段区间的颜色种数. 思路: 本来直接在线段树上染色,lz标记颜色.每次查询的话访问线段树,求出颜色种数.结果超时了,最坏的情况下,染色可以染到叶子节点. 换成存下区间的颜色种数,这样每次查询就不用找到叶子节点了,用按位或来处理颜色种数. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace

POJ训练计划1177_Picture(扫描线/线段树+离散)

解题报告 题意: 求矩形周长和. 思路: 左扫上扫,扫过了. #include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> using namespace std; struct Seg { int lx,rx,ly,ry,h,v; friend bool operator < (Seg a,Seg b) { re

POJ训练计划2828_Buy Tickets(线段树/单点更新)

解题报告 题意: 插队完的顺序. 思路: 倒着处理数据,第i个人占据第j=pos[i]+1个的空位. 线段树维护区间空位信息. #include <iostream> #include <cstdio> #include <cstring> using namespace std; struct node { int x,v; } num[201000]; int sum[1000000],ans[201000]; void cbtree(int rt,int l,in

POJ 1151 Atlantis 扫描线+线段树

点击打开链接 Atlantis Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 17252   Accepted: 6567 Description There are several ancient Greek texts that contain descriptions of the fabled island Atlantis. Some of these texts even include maps of pa

HDU 1540 &amp;&amp; POJ 2892 Tunnel Warfare (线段树,区间合并).

~~~~ 第一次遇到线段树合并的题,又被律爷教做人.TAT. ~~~~ 线段树的题意都很好理解吧.. 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1540 http://poj.org/problem?id=2892 ~~~~ 我的代码:200ms #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #defin