线段树,区间动态和,区间划分[l, mid], [mid+1, r] 直到单个点如[0,0],每个区间记录点的个数,每个星星看作线段[x,x],插入时直接从树根更新到叶节点。
/*===============================================================
* Copyright (C) 2012 All rights reserved.
*
* file: 2352_Stars.cpp
* author: ivapple
* date: 2012-05-14
* description:
* using segment tree
*
* update log:
*
================================================================*/
#include <cstdlib>
#include <cstdio>
#include <iostream>
#define out(x) (cout<<#x<<": "<<x<<endl)
#define FOR(i,s,t) for(i=s; i<t; i++)
using namespace std;
template<class T>void show(T a, int n){int i; for(i=0;i<n;i++)cout<<a[i]<<" ";cout<<endl;}
template<class T>void show(T a, int r, int l){int i; for(i=0;i<r;i++)show(a[i],l);cout<<endl;}
const int MAX_STARS = 15000;
const int MAX_X = 32000;
const int MAX_NODE = 2*(MAX_X+1);
struct SegTree
{
int s, e;
int lc, rc;
int sum;
};
SegTree tree[MAX_NODE];
int id;
void build(int l, int r)
{
int root = id;
int mid;
tree[root].s = l;
tree[root].e = r;
id++;
if (l < r)
{
mid = (l+r)/2;
// cout << l<<" " << r << endl;
tree[root].lc = id;
build(l, mid);
tree[root].rc = id;
build(mid+1, r);
}
}
void insert(int l, int r, int root)
{
int mid;
tree[root].sum++;
if (tree[root].s == tree[root].e)
return;
mid = (tree[root].s+tree[root].e)/2;
if (l<=mid)
insert(l, r, tree[root].lc);
if (r>=mid+1)
insert(l, r, tree[root].rc);
}
int search(int l, int r, int root)
{
int mid;
int re = 0;
if (l<=tree[root].s && tree[root].e<=r)
return tree[root].sum;
mid = (tree[root].s+tree[root].e)/2;
if (l<=mid)
re += search(l, r, tree[root].lc);
if (r>=mid+1)
re += search(l, r, tree[root].rc);
return re;
}
int N;
int level[MAX_STARS+1];
int main()
{
int x, y;
int l;
int i;
#ifndef ONLINE_JUDGE
freopen("test.txt", "r", stdin);
#endif
scanf("%d", &N);
//cout << N;
build(0, MAX_X);
FOR(i,0,N)
{
scanf("%d%d", &x, &y);
// cout << x << " " << y << endl;
l = search(0, x, 0);
level[l]++;
insert(x, x, 0);
}
//cout << "dd" << endl;
for (i=0; i<N; i++)
printf("%d\n", level[i]);
}