POJ-2481 Cows---树状数组的运用

题目链接:

https://vjudge.net/problem/POJ-2481

题目大意:

if Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj, we say that cow i is stronger than cow j

此处的含义就是线段[Sj, Ej]是线段[Si, Ei]的真子集,最后需要求出每条线段是多少条线段的真子集。

解题思路:

此处可以先对E坐标从大到小排序,相同的E对S从小到大排序,排完序后直接把S放入树状数组中,求出当前在树状数组中有多少比当前S小的数目。

由于E坐标从大到小,所以在某个线段放之前,终点在该线段的后面的线段已经全部加入了树状数组。而S比当前S小的线段一定是真包含该线段的。

WA点:注意此处求的是被多少线段真包含,所以在排序之后需要判断,如果两者线段一样那么就直接用前面的结果更新后面的结果。

 

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<iostream>
 4 #include<algorithm>
 5 #include<string>
 6 #include<cmath>
 7 #include<set>
 8 #include<queue>
 9 #include<map>
10 #include<stack>
11 #include<vector>
12 #include<list>
13 #include<deque>
14 #include<sstream>
15 #include<cctype>
16 #define REP(i, n) for(int i = 0; i < (n); i++)
17 #define FOR(i, s, t) for(int i = (s); i < (t); i++)
18 using namespace std;
19 typedef long long ll;
20 int T, n, m, cases;
21 const int maxn = 100100;
22 struct node
23 {
24     int x, y, id;
25     bool operator < (const node & a)const
26     {
27         return y > a.y || (y == a.y && x < a.x);
28     }
29 }a[maxn];
30 int tree[maxn];
31 int ans[maxn];
32 int lowbit(int x)
33 {
34     return x&(-x);
35 }
36 int sum(int x)
37 {
38     int ret = 0;
39     while(x > 0)
40     {
41         ret += tree[x];
42         x -= lowbit(x);
43     }
44     return ret;
45 }
46 void add(int x, int d)
47 {
48     while(x < maxn)
49     {
50         tree[x] += d;
51         x += lowbit(x);
52     }
53 }
54 int main()
55 {
56     while(scanf("%d", &n) && n)
57     {
58         memset(tree, 0, sizeof(tree));
59         memset(ans, 0, sizeof(ans));
60         memset(a, 0,sizeof(a));
61         for(int i = 1; i <= n; i++)
62         {
63             scanf("%d%d", &a[i].x, &a[i].y);
64             a[i].x++; a[i].y++;
65             a[i].id = i;
66         }
67         sort(a + 1, a + n + 1);
68         for(int i = 1; i <= n; i++)
69         {
70             if(a[i].x == a[i - 1].x && a[i].y == a[i - 1]. y)ans[a[i].id] = ans[a[i - 1].id];
71             else ans[a[i].id] = sum(a[i].x);
72             add(a[i].x, 1);
73         }
74         for(int i = 1; i <= n; i++)
75         {
76             printf("%d ", ans[i]);
77             ///若在此处在if判断是否输出空格会超时,以后就先输出a[1],然后依次输出空格+数字
78         }
79         printf("\n");
80     }
81 }

 

posted @ 2018-04-25 15:42  _努力努力再努力x  阅读(188)  评论(0编辑  收藏  举报