正题
题目链接:
http://poj.org/problem?id=2481
题目大意
给出若干个区间[Si,Ei],定义一个区间比另一个区间“strong”当且仅当Si<=Sj and Ei>=Ej and Ei-Si>Ej-Sj。输出对于每一个区间,有多少个区间比它strong。区间最多100000个,区间坐标不超过100000。
解题思路
将e从大到小排序,如果e等于就将s从小到大排序。然后用树状数组表示Si==x的数量,然后每次因为e是降序所有只有可能strong与i比其大的牛,然后在s和e都相等的情况下特殊处理就好了。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct co{
int num,s,e,w;
}cow[100001];
int c[100001],n,maxs;
int lowbit(int x)
{return x&(-x);}
void change(int x,int num)//改变
{
int i=x;
while(i<=maxs)
{
c[i]+=num;
i+=lowbit(i);
}
}
int getsum(int x)//求和
{
int sum=0;
while (x>0)
{
sum+=c[x];
x-=lowbit(x);
}
return sum;
}
bool cmp(co x,co y)//排序
{
if (x.e==y.e) return x.s<y.s;
return x.e>y.e;
}
bool cmp2(co x,co y)//排序回来
{
return x.num<y.num;
}
int main()
{
while(true)
{
scanf("%d",&n);
if (!n) break;
memset(c,0,sizeof(c));
for (int i=1;i<=n;i++)
{
scanf("%d%d",&cow[i].s,&cow[i].e);
maxs=max(maxs,cow[i].e);
cow[i].num=i;
}
sort(cow+1,cow+1+n,cmp);//排序
int last=0,k=0;
for (int i=1;i<=n;i++)
{
if (i!=1&&cow[i].e==cow[i-1].e&&cow[i].s==cow[i-1].s)
{
cow[i].w=cow[i-1].w;
change(cow[i].s+1,1);//相等就直接赋值为上一个
}
else
{
cow[i].w=getsum(cow[i].s+1);
change(cow[i].s+1,1);
//插入
}
}
sort(cow+1,cow+1+n,cmp2);
for (int i=1;i<=n;i++)
printf("%d ",cow[i].w);
printf("\n");
}
}