题意:
有n头牛,每头牛对应一个区间[Si,Ei],如果牛j 的区间是牛i 的区间的真子集(即Si <= Sj and Ej <= Ei andEi - Si > Ej - Sj),那么就说牛i 比牛j 强壮。要你依次输出比第i头牛强壮的牛数目。
题解:
将所有的牛的E区间按从大到小排序,如果E相同则S小的排在前面。读取到第i个牛的Si和Ei,那么之前出现的牛Sj<=Si 的这些牛都比i强大了。
所以首先排序,然后树状数组中存放S坐标来算出结果。
注意:S可能为0,所以S+1处理。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> using namespace std; const int maxn = 1e5+100; int c[maxn]; int lowbit(int x) { return x & -x; } int sum(int x) { int res=0; while(x>0) { res+=c[x]; x -= lowbit(x); } return res; } void add(int x,int v) { while(x<maxn) { c[x]+=v; x+=lowbit(x); } } struct node { int s,e,index; bool operator < (const node& a)const { if(e!=a.e) return e>a.e; return s<a.s; } }cows[maxn]; int ans[maxn];//ans[i]=x; x头牛比i号牛强 int main() { int n; while(cin>>n,n) { for(int i=1;i<=n;i++) { scanf("%d%d",&cows[i].s,&cows[i].e); cows[i].s++; cows[i].index=i; } sort(cows+1,cows+n+1); memset(c,0,sizeof c); ans[cows[1].index]=0; add(cows[1].s,1); for(int i=2;i<=n;i++) { if(cows[i].s ==cows[i-1].s &&cows[i].e==cows[i-1].e)///相同 ans[cows[i].index] = ans[cows[i-1].index]; else ans[cows[i].index] = sum(cows[i].s); add(cows[i].s,1); } for(int i=1;i<=n;i++) { printf("%d ",ans[i]); } puts(""); } }