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