Description
Input
Output
Sample Input
3 1 2 0 3 3 4 0
Sample Output
1 0 0
题意:当Si <= Sj & Ej <= Ei & Ei - Si > Ej - Sj则说i牛比j牛强壮,输出每个牛,一共有几头牛比第i头牛强壮
思路:首先我们可以先按s排序,得到序列后,我们就只需要找i之前的所有牛中有几头牛的e比i的e大,则可以得到答案,并且没处理完一头牛,就要对线段树进行更新
#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int n; struct node { int l,r,id; } a[1000000]; int sum[1000000],num[1000000]; //sum[i]为区间内牛的个数 //num[i]为第i头牛有几个比它强壮的 int cmp(node x,node y)//先按头小的排序,再按尾大的排序 { if(x.l == y.l) return x.r >y.r; return x.l<y.l; } void init(int i,int l,int r,int x)//统计每个区间牛的个数 { sum[i]++; if(l == r) { return ; } int mid = (l+r)>>1; if(x<=mid) init(2*i,l,mid,x); else init(2*i+1,mid+1,r,x); } int insert(int i,int l,int r,int L,int R) { int ss = 0; if(L<=l && r<=R)//找出线段树中所有尾比所要统计的牛的尾大的牛的数目 return sum[i]; int mid = (l+r)>>1; if(L<=mid) ss+=insert(2*i,l,mid,L,R); if(R>mid) ss+=insert(2*i+1,mid+1,r,L,R); return ss; } int main() { int i,j,x,y; while(~scanf("%d",&n),n) { for(i = 1; i<=n; i++) { scanf("%d%d",&a[i].l,&a[i].r); a[i].id = i; } memset(sum,0,sizeof(sum)); sort(a+1,a+n+1,cmp); for(i = 1; i<=n; i++) { if(i!=1 && a[i].l == a[i-1].l && a[i].r == a[i-1].r)//保证ei-si!=ej-sj num[a[i].id] = num[a[i-1].id]; else num[a[i].id] = insert(1,1,100001,a[i].r,100001);//统计 init(1,1,100001,a[i].r);//每统计完一头牛就更新到线段树中 } printf("%d",num[1]); for(i = 2; i<=n; i++) printf(" %d",num[i]); printf("\n"); } return 0; }