POJ 2481 Cows 线段树

来源:互联网 发布:大唐麻将辅助软件 编辑:程序博客网 时间:2024/05/16 00:26
  这题比牛i强的牛的个数就是在图上的位置是除了本身,<= x, >= y,的区域的点的个数,就是左上方的个数,所以我们可以按y降序,x升序排列,建立线段树,求点左边的点的个数,要注意处理同样位置的牛。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#define mem(a) memset(a, 0, sizeof(a))#define maxn 100000using namespace std;long ans[maxn + 5], ress, flag;struct tree{long sum;}tr[maxn * 4 + 5];struct point{long x;long y;long num;}po[maxn + 5];bool cmp(const struct point & a, const struct point & b){if(a.y > b.y)return true;else if(a.y < b.y)return false;else if(a.y == b.y){if(a.x < b.x)return true;elsereturn false;}}void build(long l, long r, long n){tr[n].sum = 0;if(l == r)return;long mid = (l + r) / 2;build(l, mid, n * 2);build(mid + 1, r, n * 2 + 1);}void add(long l, long r, long n, long x){if(flag == 1)return;    tr[n].sum++;if(l == r&&l == x){flag = 1;return;}long mid = (l + r) / 2;if(x <= mid)add(l, mid, n * 2, x);elseadd(mid + 1, r, n * 2 + 1, x);}void res(long l, long r, long n, long x){if(r == x){if(l == 0)ress += tr[n].sum;else{ress += tr[n].sum;res(0, maxn, 1, l - 1);}return;}long mid = (l + r) / 2;if(x <= mid)res(l, mid, n * 2, x);elseres(mid + 1, r, n * 2 + 1, x);}int main(int argc, char *argv[]){long num, x, y, i, tx, ty, tnum;while(scanf("%ld", &num)){if(num == 0)break;mem(ans);mem(tr);mem(po);build(0, maxn, 1);for(i = 0;i < num;i++){scanf("%ld%ld", &po[i].x, &po[i].y);            po[i].num = i;}sort(po, po + num, cmp);for(i = 0;i < num;i++){if(i != 0&&tx == po[i].x&&ty == po[i].y){    ans[po[i].num] = ans[tnum];    flag = 0;    add(0, maxn, 1, po[i].x);    continue;}    ress = 0;flag = 0;res(0, maxn, 1, po[i].x);ans[po[i].num] = ress;flag = 0;add(0, maxn, 1, po[i].x);tx = po[i].x;ty = po[i].y;tnum = po[i].num;}for(i = 0;i < num;i++){if(i != (num - 1))printf("%ld ", ans[i]);elseprintf("%ld\n", ans[i]);}}return 0;}

0 0