poj 2481 树状数组(覆盖每个区间的区间个数)

题意:在数轴[0,100000]内给定n个区间,区间端点为整数。问对于每个区间,有多少个区间能够包含这个区间。如果两个区间端点全部相同不算包含,只有一个端点相同的属于包含关系。

思路:树状数组。按照终止节点从大到小排序,相同的则按照起始节点从小到大,目的使得只有前面的区间可能包含后面的区间。遍历n处理两种情况:1、区间的两端点都和上一个完全相同,则输出值也和上一个区间相同;2、如果不是,那么计算该区间左端点之前有多少个左端点,也就是有多少个区间能够覆盖当前区间。最后将该区间的左端点树状数组进行更新。显然这种需要反复求和的问题用树状数组来做。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define N 100005
struct node{
	int a,b,id;
}p[N];
int n,res[N],t[N];
int cmp(const struct node *a,const struct node *b){
	if((*a).b == (*b).b)
		return (*a).a - (*b).a;
	return (*b).b - (*a).b;
}
int lowbit(int x){
	return x&(-x);
}
int sum(int x){
	int i,sum=0;
	for(i = x;i>0;){
		sum += t[i];
		i -= lowbit(i);
	}
	return sum;
}
void add(int x){
	int i;
	for(i = x;i<N;){
		t[i] += 1;
		i += lowbit(i);
	}
}
int main(){
	freopen("a.txt","r",stdin);
	while(scanf("%d",&n) && n){
		int i;
		memset(t,0,sizeof(t));
		for(i = 0;i<n;i++){
			scanf("%d %d",&p[i].a,&p[i].b);
			p[i].id = i;
		}
		qsort(p,n,sizeof(struct node),cmp);
		for(i = 0;i<n;i++){
			if(i && p[i].a==p[i-1].a && p[i].b==p[i-1].b)
				res[p[i].id] = res[p[i-1].id];
			else
				res[p[i].id] = sum(p[i].a+1);
			add(p[i].a+1);
		}
		for(i = 0;i<n;i++)
			printf("%d ",res[i]);
		putchar('\n');
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值