每个牛有一个区间[s,e],两个牛[s1,e1], [s2,e2],当s1<=s2并且e1>=e2并且e1-s1>e2-s2时,我们说牛1比牛2强,给N个牛的区间,对于每个牛,输出比这个牛强的牛的个数。
还是需要预处理,先对每个牛的e进行降序排序,e相同时对s进行升序排列,这样循环时可以保证后边的牛绝对不比前边的牛强。在循环时,只需找出比当前牛s小的牛的个数。如果遇到特殊情况,即两个牛区间完全一样,赋值就可以了。
#include <cstdio> #include <cstring> #include <algorithm> #include <map> #define MAX 100002 using namespace std; int c[MAX],ans[MAX],n,imax; struct cow { int l,r,id; }a[MAX]; bool cmp(cow a,cow b){ if(a.r==b.r) //如果两个牛区间右边界相同,按左边界的升序排列 return a.l<b.l; return a.r>b.r; //按右边界的降序排列 } int lowbit(int t){ return t&(t^(t-1)); } int sum(int t){ int total=0; while(t>0){ total+=c[t]; t-=lowbit(t); } return total; } void modify(int posi,int key){ while(posi<=imax){ c[posi]+=key; posi+=lowbit(posi); } } int main() { int i,j,k,n; while(scanf("%d",&n),n){ memset(c,0,sizeof(c)); imax=0; for(i=1;i<=n;i++){ scanf("%d%d",&a[i].l,&a[i].r); a[i].id=i; //每个牛有个id防止排序完顺序变乱 ++a[i].l; ++a[i].r; if(imax<a[i].l) imax=a[i].l; //用imax表示右边界最大值,即求和时的边界 } sort(a+1,a+n+1,cmp); for(i=1;i<=n;++i){ if(i==1){ ans[a[i].id]=sum(a[i].l); //这里注意是ans[a[i].id]而不是ans[i] modify(a[i].l,1); } else{ if(a[i].l==a[i-1].l&&a[i].r==a[i-1].r) //如果两个牛完全相同,直接赋值 ans[a[i].id]=ans[a[i-1].id]; else ans[a[i].id]=sum(a[i].l); //否则找出左边界l比这个牛小的 modify(a[i].l,1); } } for(i=1;i<n;++i) printf("%d ",ans[i]); printf("%d/n",ans[i]); } }