题意:给出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;
}