您的位置:首页 > 其它

URAL 1028 Stars

2012-05-02 21:29 323 查看
URAL_1028

将点排序后依次插入线段树,就可以将计算星星等级转化成区间求和的问题了,于是用线段树支持单点修改和区间求和即可。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXD 15010
#define MAXX 32010
struct Point
{
int x, y;
}p[MAXD];
const int D = 32000;
int N, num[4 * MAXX], h[MAXD];
int cmp(const void *_p, const void *_q)
{
Point *p = (Point *)_p, *q = (Point *)_q;
if(p->y == q->y)
return p->x < q->x ? -1 : 1;
return p->y < q->y ? -1 : 1;
}
void init()
{
int i, j, k;
for(i = 0; i < N; i ++)
scanf("%d%d", &p[i].x, &p[i].y);
qsort(p, N, sizeof(p[0]), cmp);
memset(num, 0, sizeof(num));
}
void update(int cur)
{
num[cur] = num[cur << 1] + num[(cur << 1) | 1];
}
int Search(int cur, int x, int y, int s, int t)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
if(x >= s && y <= t)
return num[cur];
if(mid >= t)
return Search(ls, x, mid, s, t);
else if(mid + 1 <= s)
return Search(rs, mid + 1, y, s, t);
else
return Search(ls, x, mid, s, t) + Search(rs, mid + 1, y, s, t);
}
void refresh(int cur, int x, int y, int k)
{
int mid = (x + y) >> 1, ls = cur << 1, rs = (cur << 1) | 1;
if(x == y)
{
++ num[cur];
return ;
}
if(k <= mid)
refresh(ls, x, mid, k);
else
refresh(rs, mid + 1, y, k);
update(cur);
}
void solve()
{
int i, j, k;
memset(h, 0, sizeof(h));
for(i = 0; i < N; i ++)
{
k = Search(1, 0, D, 0, p[i].x);
++ h[k];
refresh(1, 0, D, p[i].x);
}
for(i = 0; i < N; i ++)
printf("%d\n", h[i]);
}
int main()
{
while(scanf("%d", &N) == 1)
{
init();
solve();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: