POJ 2352 Stars (线段树)

线段树,区间动态和,区间划分[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]);
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值