poj2481 Cows

题意:

给出n头牛,他们有两个属性x和y,当A牛的x比B牛的x小于或等于,A牛的y比B牛的y大于或等于,但x和y不能同时等于,则称为A牛比B牛更强大

问对每头牛,有多少头牛比他强大

解法:

poj2352 Stars,只是要将x离散化,并且是求左上角的个数

代码中有注释

代码:

#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
using namespace std;
class node
{
public:
	int x,y;
	int num;//一开始的编号
	int ans;//比该牛的强大的牛的个数,即最后结果
}cow[100010];
int n;
int tempx[100010];//将牛的x坐标另外存储一份,离散化使用
int turn[100010];//x坐标离散化后的值
int c[100010];//树状数组
bool cmp1(int a,int b)
{
	return a<b;
}
bool cmp2(node a,node b)
{
	if(a.y==b.y)
	{
		return a.x<b.x;
	}
	return a.y>b.y;
}
int lowbit(int x)
{
	return x&(-1*x);
}
int getsum(int x)//树状数组的求和函数
{
	int res=0;
	while(x>=1)
	{
		res+=c[x];
		x-=lowbit(x);
	}
	return res;
}
void updata(int x)//树状数组的插入函数
{
	while(x<=n)
	{
		c[x]++;
		x+=lowbit(x);
	}
}
bool cmp3(node a,node b)
{
	return a.num<b.num;
}
int main()
{
	while(scanf("%d",&n),n)
	{
		for(int i=1;i<=n;i++)
		{
			scanf("%d %d",&cow[i].x,&cow[i].y);
			tempx[i]=cow[i].x;
			cow[i].num=i;
		}//输入数据
		sort(tempx+1,tempx+n+1,cmp1);//将所有的x坐标进行排序
		int *tempn=unique(tempx+1,tempx+n+1);//将重复的坐标除去
		for(int i=1;i+tempx<tempn;i++)
		{
			turn[tempx[i]]=i;//离散化过程
		}
		for(int i=1;i<=n;i++)
		{
			cow[i].x=turn[cow[i].x];
		}
		//离散化完成
		sort(cow+1,cow+n+1,cmp2);//将牛按照从强到弱排序
		memset(c,0,sizeof(c));//树状数组置0
		for(int i=1;i<=n;i++)
		{
			if(i!=1&&cow[i].x==cow[i-1].x&&cow[i].y==cow[i-1].y)//对于两头牛x和y均相同时的特判
			{
				cow[i].ans=cow[i-1].ans;
				updata(cow[i].x);
				continue;
			}
			updata(cow[i].x);
			cow[i].ans=getsum(cow[i].x)-1;
		}
		sort(cow+1,cow+n+1,cmp3);//排回原来的顺序
		for(int i=1;i<n;i++)//输出答案
		{
			printf("%d ",cow[i].ans);
		}
		printf("%d\n",cow[n].ans);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值