ural 1028 Stars [线段树]

来源:互联网 发布:nfc卡模拟软件 编辑:程序博客网 时间:2024/05/21 17:43

题意:给n个星星的坐标(x,y),其中1 ≤ N ≤ 15000,0 ≤ X,Y ≤ 32000,定义星星的等级为在它的左下方的星星的数目(横纵坐标均可相等),要求输出等级为0~n-1的星星的数目

思路:首先不可能暴力两重循环,自然是线段树。由于给的星星是按照纵坐标的升序排列的,只要一维地对x做处理就行了。

线段树跟堆好像23333~

#include <cstdio>#include <cstring>struct Node{int a, b, cover;Node() {}Node(int _a, int _b): a(_a), b(_b), cover(0) {}int middle() { return (a+b)>>1; }} t[66000];void build(int a, int b, int d){t[d] = Node(a,b);if (a >= b) return ;int mid = (a+b) >> 1;build(a,mid,2*d+1);build(mid+1,b,2*d+2);}void add(int n, int d){t[d].cover ++;if (t[d].a == t[d].b) return ;int mid = t[d].middle();if (mid >= n) add(n, 2*d+1);else add(n,2*d+2);}int quary(int a, int b, int d){if (a==t[d].a && b==t[d].b) return t[d].cover;int mid = t[d].middle();if (mid >= b) return quary(a,b,2*d+1);else if (mid < a) return quary(a,b,2*d+2);else return quary(a,mid,2*d+1) + quary(mid+1,b,2*d+2);}int num, x, y;int level[15005];int main(){while (scanf("%d",&num) != EOF){memset(level,0,sizeof(level));build(0,32000,0);for (int i = 0; i < num; ++ i){scanf("%d%d",&x,&y);level[quary(0,x,0)] ++;add(x,0);}for (int i = 0; i < num; ++ i)printf("%d\n", level[i]);}}