地址:http://poj.org/problem?id=2481
题意:n只羊,每只羊占有一个[S,E]。如果一只羊的区间囊括它,而且长度比它长,就说明这只羊比它大。求每只羊比它本身大的羊的数目。
解析:
这道题和LOJ10114数星星:https://www.cnblogs.com/liyexin/p/12853300.html 基本一致。
只是这道题需要自己排下序。
可以发现,如果把每个区间看成坐标的话,比它大的,其实就是位于它左上角的坐标点,求这个数目即可。
排序:
(x,y)。对于y不同的,直接降序排列,y相同的,x升序排列。这样判断的时候,直接看它前面的x值就可以了。
这个数目由树状数组来维护,接下来就是基本操作了。
#include<iostream> #include<cstdio> #include<cmath> #include<algorithm> #include<cstring> using namespace std; typedef long long ll; const int maxn=1e5+10; struct node { int id,x,y; }st[maxn]; int num[maxn]; int n; int c[maxn]; bool cmp(node a,node b) { if(a.y!=b.y) return a.y>b.y; else return a.x<b.x; } int lowbit(int x) { return x&(-x); } void update(int id) { for(int i=id;i<maxn;i+=lowbit(i)) c[i]++; } int getsum(int id) { int ans=0; for(int i=id;i>=1;i-=lowbit(i)) ans+=c[i]; return ans; } int main() { while(scanf("%d",&n)&&n) { for(int i=1;i<=n;i++) { scanf("%d%d",&st[i].x,&st[i].y),st[i].id=i; st[i].x++; //树状数组,不要有0 st[i].y++; } memset(num,0,sizeof(num)); memset(c,0,sizeof(c)); sort(st+1,st+1+n,cmp); for(int i=1;i<=n;i++) { if(i!=1&&st[i].x==st[i-1].x&&st[i].y==st[i-1].y) { num[st[i].id]=num[st[i-1].id]; //相同的点,就继承它的数目就可以了。 } else { num[st[i].id]=getsum(st[i].x); } update(st[i].x); } for(int i=1;i<n;i++) cout<<num[i]<<" "; cout<<num[n]<<endl; } }