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 }
越努力,越幸运