Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 15834 | Accepted: 5271 |
Description
Input
Output
Sample Input
3
1 2
0 3
3 4
0
Sample Output
1 0 0
题意:有N头牛,每只牛有一个测试值[S,E],如果对于牛i和牛j来说,它们的测验值满足下面的条件则证明牛i比牛j强壮:Si <=Sjand Ej <= Ei and Ei - Si > Ej - Sj。现在已知每一头牛的测验值,要求输出每头牛有几头牛比其强壮。
(1<=N<=10^5,0<=S<E<=10^5)
思路:
假设现在要求的牛是i,那么比他强壮的牛的sj一定小于等于si,且ej大于等于ei(排除si==sj&&ei==ej的情况)。
所以我们可以对s按从小到大排序,s相同时e从大到小排
如果当前所求的i的s[i]==s[i-1]&&e[i]==e[i-1],那么ans[i]=ans[i-1],
否则便是查询排序后在他前面的牛的e大于等于他的数目(可以利用树状数组去维护)
#include<algorithm> #include<cstdio> #include<cstring> using namespace std; const int maxn=100100; int C[maxn],ans[maxn]; struct query{ int s,e,id; }Q[maxn]; int n,num; bool cmp(query x,query y){ if(x.s!=y.s) return x.s<y.s; return x.e>y.e; } void update(int x){ while(x<=num){ C[x]++; x+=(x&-x); } } int sum(int x){ int ret=0; while(x>0){ ret+=C[x]; x-=(x&-x); } return ret; } int main(){ while(scanf("%d",&n)!=EOF){ if(n==0) break; num=0; for(int i=1;i<=n;i++) scanf("%d%d",&Q[i].s,&Q[i].e),Q[i].id=i,num=max(num,Q[i].e); sort(Q+1,Q+n+1,cmp); memset(C,0,sizeof(C)); for(int i=1;i<=n;i++){ if(i==1) ans[Q[i].id]=0; else{ if(Q[i].s==Q[i-1].s&&Q[i].e==Q[i-1].e) ans[Q[i].id]=ans[Q[i-1].id]; else ans[Q[i].id]=i-1-sum(Q[i].e-1); } update(Q[i].e); } for(int i=1;i<=n;i++){ if(i==n) printf("%d\n",ans[i]); else printf("%d ",ans[i]); } } return 0; } /* 5 1 2 0 3 2 4 3 6 3 10 */