/* 参考:http://hi.baidu.com/acfordream/blog/item/64b1527f7a5398f90ad187f6.html 这个题大概是计算,一个区间会被多少区间覆盖的问题: 标准做法:套用别人写的 给定 n 个区间 (l, r),问每个区间被多少个另外的区间所包含。 包含的定义 (l1, r1), (l2, r2),如果 l1 <= l2 < r2 <= r1 && (l1, r1) != (l2, r2),则 (l1, r1) 包含 (l2, r2)。 用节点存储区间,然后给节点排序。l 小的区间放在前面,l 相同则 r 大的区间放在前面。 为什么这样排序呢?因为对排序之后的节点,节点 n 只可能被排在它前面的 (0 —— n-1) 号节点包含,而不可能被后面的包含。 那么(0——n-1) 号节点中,又哪些能包含节点 n 呢?只要 ri >= rn 即可。(因为 li <= ln的)。, r),问每个区间被多少个另外的区间所包含。 包含的定义 (l1, r1), (l2, r2),如果 l1 <= l2 < r2 <= r1 && (l1, r1) != (l2, r2),则 (l1, r1) 包含 (l2, r2)。 用节点存储区间,然后给节点排序。l 小的区间放在前面,l 相同则 r 大的区间放在前面。 为什么这样排序呢?因为对排序之后的节点,节点 n 只可能被排在它前面的 (0 —— n-1) 号节点包含,而不可能被后面的包含。 那么(0——n-1) 号节点中,又哪些能包含节点 n 呢?只要 ri >= rn 即可。(因为 li <= ln的)。 */ #include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; const int N=100009; struct inv { int u,v,num; }Cow[N]; int cnt[N],Max; bool cmp(inv x,inv y) { if(x.v!=y.v)return x.v>y.v; return x.u<y.u; } int ar[N]; int lowb(int t){return t&(-t);} void add(int i,int v) { for(;i<N;ar[i]+=v,i+=lowb(i)); } int sum(int i) { int s=0; for(;i>0;s+=ar[i],i-=lowb(i)); return s; } int main() { int n,x,y; while(scanf("%d",&n),n) { memset(ar,0,sizeof(ar)); Max=-1; for(int i=0;i<n;i++) { scanf("%d%d",&x,&y); Cow[i].u=++x; Cow[i].v=++y; if(y>Max)Max=y; Cow[i].num=i; } sort(Cow,Cow+n,cmp); for(int i=0;i<n;i++) { if(i>0&&Cow[i].u==Cow[i-1].u&&Cow[i].v==Cow[i-1].v) cnt[Cow[i].num]=cnt[Cow[i-1].num]; else { cnt[Cow[i].num]=sum(Cow[i].u); } add(Cow[i].u,1); } for(int i=0;i<n-1;i++) printf("%d ",cnt[i]); printf("%d\n",cnt[n-1]); } } //第二种方式:区间后边界排序 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define N 100001 struct Node{ int s,e,index; }node[100001]; int res[N]; int s1[100001]; bool cmp(const Node &a, const Node &b){ if(a.s==b.s) return a.e>b.e; else return a.s<b.s; } int lowbit(int key){ return key&(-key); } void add1(int index,int key){ for(int i=index; i<=N; i+=lowbit(i)){ s1[i]+=key; } } int getsum1(int index){ int ans=0; for(int i=index; i>0; i-=lowbit(i)){ ans+=s1[i]; } return ans; } int main(){ int n; while(scanf("%d",&n)&&n){ for(int i=0; i<n; i++){ scanf("%d%d",&node[i].s,&node[i].e); node[i].index=i; } sort(node, node+n, cmp); memset(s1,0,sizeof(s1)); //初始化 memset(res,0,sizeof(res)); res[node[0].index]=0; add1(node[0].e,1); int mmax = node[0].e; for(int i=1; i<n; i++){ if(node[i].e==node[i-1].e&&node[i].s==node[i-1].s){ res[node[i].index]=res[node[i-1].index]; add1(node[i].e,1); //将节点压入栈中 continue; } res[node[i].index] = getsum1(mmax) - getsum1(node[i].e-1); add1(node[i].e,1); if(node[i].e>mmax) mmax = node[i].e; } printf("%d",res[0]); for(int i=1; i<n; i++){ printf(" %d",res[i]); } printf("\n"); } return 0; }