Cows POJ - 2481 (树状数组

题目链接

题意:有N头牛,每只牛有一个测试值[S,E],如果对于牛i和牛j来说,它们的测验值满足下面的条件则证明牛i比牛j强壮:Si <= Sj and Ej <= Ei and Ei - Si > Ej - Sj。现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮。

        给你一些区间,问,对于给出的每个区间,有多少个区间是完全包含它的。
        先将S从小到大排序,E从大到小排序,这样就可以保证在放入一个区间里,前面所以放下的区间的左端点都是小于等于它的。那么,这时候查询,有多少个区间的右端点是大于等于它的右端点的,就可以得出答案。
        需要注意的是,在查询的时候,如果当前区间和前面一个区间是完全相同的话,那么直接将前面的区间得到的答案赋给它就可以,不然,查询大于等于它的右端点的数目。还有就是离散化。

ac代码

#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
 
using namespace std;
struct Node{
	int s,e;
	int id;
}node[100005];
int ans[100005],d[100005],n;
int lowbit(int k)
{
	return k&(-k);
}
bool cmp(Node a,Node b)
{
	if(a.e != b.e)return a.e > b.e;
	return a.s < b.s; 
}
void add(int pos,int v)
{
	while (pos <= n)
	{
		d[pos]+=v;
		pos += lowbit(pos);
	}
}
int read(int k)
{
	int sum=0;
	while(k>0){
		sum+=d[k];
		k-=lowbit(k);
	}
	return sum;
}
int main(){
	while(scanf("%d",&n),n)
   {
		memset(ans,0,sizeof(ans));
		memset(d,0,sizeof(d));
		for(int i=0;i<n;i++)
		{
			scanf("%d%d",&node[i].s,&node[i].e);
			node[i].s++;
			node[i].e++;
			node[i].id=i;
		}
		sort(node,node+n,cmp);
		ans[node[0].id]=0;
		add(node[0].s,1);
		for(int i=1;i<n;i++)
		{
			if(node[i-1].s == node[i].s && node[i-1].e == node[i].e)
				ans[node[i].id]=ans[node[i-1].id];
			else 
				ans[node[i].id] = read(node[i].s);
			add(node[i].s,1);
		}
		printf("%d",ans[0]);
		for(int i=1;i<n;i++)
			{
				printf(" %d",ans[i]);
			}
		printf("\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_xujiu/article/details/81237179
今日推荐