题意:输入n组数据,每组数据由n行样例组成,分别代表每头牛食草的左区间和右区间,如果牛A的食草区域是牛B的真子集,则说明牛B比牛Astrong,结果输出比该牛strong的牛的头数
思路:将牛的右区间按照从大到小排序,比较每头牛前面有几头牛的左区间小于该牛,得到的结果就是比该牛strong的牛的头数(与之前那道star题类似,都是先固定一个变量的顺序,然后比较另一个变量)
ACCODE :
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
const int N=100005;
int c[N],n,m,t,ans[N];
struct node
{
int s,e;
int id;
}cow[N];
int lowbit(int i)
{
return i&(-i);
}
int getsum(int x)
{
int sum=0;
while(x)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
void update(int x,int val)
{
while(x<=N)
{
c[x]+=val;
x+=lowbit(x);
}
}
int cmp(node a,node b)
{
if(a.e==b.e)
{
return a.s<b.s;
}else return a.e>b.e;
}//将右区间从大到小排列;如果右区间相同,则将左区间小的排在前面
int main()
{
while(scanf("%d",&n)!=EOF&&n)
{
memset(ans,0,sizeof(ans));
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
scanf("%d%d",&cow[i].s,&cow[i].e);
cow[i].s++;//树状数组都是从1开始,因此要将s加1,防止出现0
cow[i].id=i;
}
sort(cow+1,cow+1+n,cmp);
ans[cow[1].id]=0;//排在最前面的第一头牛是无敌的 ~
update(cow[1].s,1);//更新数组
for(int i=2;i<=n;i++)
{
if(cow[i].s==cow[i-1].s&&cow[i].e==cow[i-1].e)//如果两头牛的左右区间均相等,ans的值相等,直接赋值
{
ans[cow[i].id]=ans[cow[i-1].id];
}else ans[cow[i].id]=getsum(cow[i].s);
update(cow[i].s,1);
}
for(int i=1;i<=n;i++)
{
printf("%d ",ans[i]);
}printf("\n");
}return 0;
}