Cows(poj 2481 树状数组)

Cows

Time Limit: 3000MS   Memory Limit: 65536K
Total Submissions: 15301   Accepted: 5095

Description

Farmer John‘s cows have discovered that the clover growing along the ridge of the hill (which we can think of as a one-dimensional number line) in his field is particularly good.

Farmer John has N cows (we number the cows from 1 to N). Each of Farmer John‘s N cows has a range of clover that she particularly likes (these ranges might overlap). The ranges are defined by a closed interval [S,E].

But some cows are strong and some are weak. Given two cows: cowi and cowj, their favourite clover range is [Si, Ei] and [Sj, Ej]. If Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cowi is stronger than cowj.

For each cow, how many cows are stronger than her? Farmer John needs your help!

Input

The input contains multiple test cases.
For each test case, the first line is an integer N (1 <= N <= 105), which is the number of cows. Then come N lines, the i-th of which contains two integers: S and E(0 <= S < E <= 105) specifying the start end location respectively of a range preferred by some cow. Locations are given as distance from the start of the ridge.

The end of the input contains a single 0.

Output

For each test case, output one line containing n space-separated integers, the i-th of which specifying the number of cows that are stronger than cowi.

Sample Input

3
1 2
0 3
3 4
0

Sample Output

1 0 0

Hint

Huge input and output,scanf and printf is recommended.

题意:两个区间:[Si, Ei] and [Sj, Ej].(0 <= S < E <= 105). 若 Si <= Sj and Ej <= Ei and Ei – Si > Ej – Sj, 则第i个区间覆盖第j个区间。给定N个区间(1 <= N <= 10^5),分别求出对于第i个区间,共有多少个区间能将它覆盖。

思路:初看好像挺复杂的。其实可以把区间[S, E]看成点(S, E),这样题目就转化为hdu 1541 Stars。只是这里是求该点左上方的点的个数。

虽然如此,我还是WA了不少,有一些细节没注意到。给点排序时是先按y由大到小排序,再按x由小到大排序。而不能先按x排序。比如n=3, [1,5], [1,4], [3,5]的例子。另外还要注意对相同点的处理。

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5
 6 const int MAX = 100010;
 7
 8 struct Node{
 9     int x, y, id, ans;
10 }seq[MAX];
11 int sum[MAX], n;
12
13 int cmp1(Node a,Node b){
14     if(a.y==b.y)  return a.x<b.x;
15     return a.y>b.y;
16 }
17 int cmp2(Node a,Node b){
18   return a.id<b.id;
19 }
20
21 int lowbit(int x){
22     return x & (-x);
23 }
24 void add(int pos, int val){
25     while(pos < MAX){
26         sum[pos]+=val;
27         pos+=lowbit(pos);
28     }
29 }
30 int getsum(int pos){
31     int res = 0;
32     while(pos>0){
33         res+=sum[pos];
34         pos-=lowbit(pos);
35     }
36     return res;
37 }
38
39 int main()
40 {
41   freopen("in.txt","r",stdin);
42   int i,j;
43    while(scanf("%d", &n) && n){
44        for(i=1;i<=n;i++){
45            scanf("%d%d", &seq[i].x, &seq[i].y);
46             seq[i].x++, seq[i].y++;
47            seq[i].id = i;
48         }
49         sort(seq+1,seq+n+1,cmp1);
50        memset(sum, 0, sizeof(sum));
51         seq[1].ans = 0;
52         add(seq[1].x, 1);
53      int fa = 1;
54       for(i=2;i<=n;i++){
55             if(seq[i].x == seq[fa].x && seq[i].y == seq[fa].y){
56                seq[i].ans = seq[fa].ans;
57             }else{
58                 fa = i;
59                seq[i].ans = getsum(seq[i].x);
60             }
61
62             add(seq[i].x, 1);
63         }
64         sort(seq+1,seq+n+1,cmp2);
65         printf("%d", seq[1].ans);
66         for(i=2;i<=n;i++) printf(" %d", seq[i].ans);
67       printf("\n");
68     }
69    return 0;
70 }  
时间: 2024-08-28 00:02:08

Cows(poj 2481 树状数组)的相关文章

POJ 2481 树状数组 区间覆盖(POJ2352 Stars 的变形题)(线段化点)

0)学会将题目情景转化为自己熟悉的结构或模型. 题目大意: 每个奶牛有自己的一个区间,求每个奶牛的区间所覆盖的子区间个数(注意,真子集,相等的不算),按照输入的顺序输出. 转化: 要学会将题目情景转化为自己熟悉的模型或结构上.把每个区间的左端x值作为点的x坐标,右端x值作为点的y坐标,就可以把所有区间转化为一个二维坐标图上的点集,而此时每个点左上方的点(同Stars那道题目一样不包括自身)的个数,就是每个区间所覆盖的子区间的个数(对应题目要求,这里或许可以再变形). 同POJ2481 Stars

poj 3067 poj 2481 树状数组变形+对区间排序

这种问题先对区间和线段进行排序,排序方法见代码cmp 然后分析其中一个点,用sum求值 poj 3067 Description Japan plans to welcome the ACM ICPC World Finals and a lot of roads must be built for the venue. Japan is tall island with N cities on the East coast and M cities on the West coast (M <

poj 2299 树状数组求逆序数+离散化

http://poj.org/problem?id=2299 最初做离散化的时候没太确定但是写完发现对的---因为后缀数组学的时候,,这种思维习惯了吧 1.初始化as[i]=i:对as数组按照num[]的大小间接排序 2.bs[as[i]]=i:现在bs数组就是num[]数组的离散化后的结果 3.注意,树状数组中lowbit(i)  i是不可以为0的,0&(-0)=0,死循环... #include <cstdio> #include <cstring> #include

Poj 2182-Lost Cows(Treap||树状数组+二分答案)

题目链接:点击打开链接 题意:n个牛编号为1-n 现在编号顺序已经打乱,给出a[i] ,a[i] 代表i位置前面有几个小于它的编号,求编号顺序. 倒着推,对于最后一个a[i] , 最后位置编号肯定是 a[i]+1,然后在1-n个编号中删掉当前编号,继续往前推..即求第 a[i]+1小数,初始容器中有n个数(1-n) ,每求出来一个就删掉.先用平衡树水了一发..明天写树状数组解法. #include <algorithm> #include <iostream> #include &

POJ 2352Stars 树状数组

Stars Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 42898   Accepted: 18664 Description Astronomers often examine star maps where stars are represented by points on a plane and each star has Cartesian coordinates. Let the level of a st

SYSU-5, POJ 2131, 树状数组+二分

题目大意:给出n个人,顺序对位置进行请求,如果第i个人请求的位置上有人,则让这个人顺延,如果顺延的位置继续有人,递归进行,问最后所有人的位置. 解:这题貌似可以用平衡树+并查集搞定,但是我队友强烈安利树状数组的做法.赛场上没出,赛后结合discuz想了一下,作一下处理. 首先如果是一个请求第a[i]个有空位置的问题,那么这个问题显然可以用树状数组维护前缀和即可.所以我们现在考虑将原问题转化成这个问题. 考虑终态,把没有人的位置去掉,剩下的n个座位排在一起,显然转化成上面模型的形式 第i个询问时,

POJ 1201 树状数组

链接: http://poj.org/problem?id=1201 题意: 给你n个区间,每个区间为[a,b],每个区间取c个数构成一个集合,求集合最小容量 题解: 把区间按b排序,从第一个区间开始取,从后往前取,这样尽可能和后面的区间重复 另外如果我们发现当前区间取得个数已经超过了c,那么只需要让之前区间换就行,而总数是不变的,所以不用更新答案 求当前区间已经取了多少个数用树状数组 代码: 1 #include <map> 2 #include <set> 3 #include

POJ 3321 树状数组(+dfs+重新建树)

Apple Tree Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27092   Accepted: 8033 Description There is an apple tree outside of kaka's house. Every autumn, a lot of apples will grow in the tree. Kaka likes apple very much, so he has been

MooFest POJ - 1990 (树状数组)

Every year, Farmer John's N (1 <= N <= 20,000) cows attend "MooFest",a social gathering of cows from around the world. MooFest involves a variety of events including haybale stacking, fence jumping, pin the tail on the farmer, and of cours