POJ - 2481 Cows(树状数组)

本文介绍了一个有趣的算法问题——通过树状数组解决奶牛与三叶草的问题。该问题需要确定每只奶牛相对于其他奶牛的相对位置,并计算出有多少只奶牛位于特定的位置上,即左上角。文章提供了详细的解决方案和完整的参考代码。

点我看题

题意:给出n只奶牛,每只都有自己喜欢的三叶草对应的区间,在自己左上角的奶牛是比自己强的奶牛,问对于每只奶牛来说,共有多少只比自己强.

分析:首先要明确一点,左上角的奶牛一定要比右下角的厉害,设左上角的奶牛对应区间为[xi,yi],右下角的为[xj,yj],那么xi<=xj&&yi>=yj,并且yi-xi>yj-xj,这是因为经过一趟排序之后得到的.知道这些之后,就可以利用树状数组来解决问题了,Sum函数来求当前奶牛比多少只奶牛弱,Update更新当前只奶牛对后面的影响.

参考代码:

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>

using namespace std;
const int maxn = 1e5+10;
int n;
struct Node{
	int x,y;
	int index;
};
Node c[maxn];
int sum[maxn];
int cnt[maxn];

bool cmp( Node a, Node b)//这边的比较函数一定要按照严格的方式这样写,不然的话对于y相等x而xi>xj这样的数据可能会出问题
{
	if( a.y != b.y)
		return a.y > b.y;
	return a.x < b.x;
}

inline int lowbit( int x)
{
	return x&-x;
}

int Sum( int x)
{
	int ans = 0;
	while( x)
	{
		ans += sum[x];
		x -= lowbit(x);
	}
	return ans;
}

void Update( int x)
{
	while( x < maxn)
	{
		sum[x]++;
		x += lowbit(x);
	}
}

int main()
{
	while( ~scanf("%d",&n) && n)
	{
		for( int i = 1; i <= n; i++)
		{
			scanf("%d%d",&c[i].x,&c[i].y);
			c[i].index = i;
		}
		sort(c+1,c+1+n,cmp);
		memset(sum,0,sizeof(sum));
		memset(cnt,0,sizeof(cnt));

		cnt[c[1].index] = 0;
		Update(c[1].x+1);
		for( int i = 2; i <= n; i++)
		{
			if( c[i].y == c[i-1].y && c[i].x == c[i-1].x)
				cnt[c[i].index] = cnt[c[i-1].index];
			else
				cnt[c[i].index] = Sum(c[i].x+1);
			Update(c[i].x+1);
		}

		for( int i = 1; i < n; i++)
			printf("%d ",cnt[i]);
		printf("%d\n",cnt[n]);
	}

	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值