正题
题目链接:
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");}
}