codeforces 652D D. Nested Segments(离散化+sort+树状数组)
题目链接:
time limit per test
2 secondsmemory limit per test
256 megabytesinput
standard inputoutput
standard outputYou are given n segments on a line. There are no ends of some segments that coincide. For each segment find the number of segments it contains.
Input
The first line contains a single integer n (1 ≤ n ≤ 2·105) — the number of segments on a line.
Each of the next n lines contains two integers li and ri ( - 109 ≤ li < ri ≤ 109) — the coordinates of the left and the right ends of the i-th segment. It is guaranteed that there are no ends of some segments that coincide.
Output
Print n lines. The j-th of them should contain the only integer aj — the number of segments contained in the j-th segment.
Examples
input
4
1 8
2 3
4 7
5 6
output
3
0
1
0
input
3
3 4
1 5
2 6
output
0
1
1
题意:给n个线段,对于每个线段问它覆盖了多少个线段;
思路:由于线段端点是在e9范围内,所以要先离散化到2e5内,只离散化一个端点即可,我离散化的是右端点,然后在对左端点排序(保证l[i]>=l[j]),然后再按顺序query右端点(保证r[i]<r[j])并update,就可以得到结果了,感觉线段树和树状数组真是丧心病狂;还有以前不会离散化,昨天睡觉的时候居然自己就领悟了,哈哈哈哈哈,开心;
AC代码:
/*2014300227 652D - 24 GNU C++11 Accepted 187 ms 5948 KB */ #include <bits/stdc++.h> using namespace std; const int N=2e5+3; int n,sum[N],ans[N]; struct node { int l,r,id; }; node qu[N]; bool cmp1(node x,node y) { if(x.r==y.r)return x.l<y.l; return x.r<y.r; } bool cmp2(node x,node y) { if(x.l==y.l)return x.r<y.r;//注意此处的大小关系,因为我把右端点相等的离散化成不等的了; return x.l>y.l; } int lowbit(int x) { return x&(-x); } void update(int x) { while(x<=n) { sum[x]++; x+=lowbit(x); } } int query(int x) { int s=0; while(x>0) { s+=sum[x]; x-=lowbit(x); } return s; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d%d",&qu[i].l,&qu[i].r); qu[i].id=i; } sort(qu+1,qu+n+1,cmp1);//按右端点排序以离散化 for(int i=1;i<=n;i++) { qu[i].r=i;//离散化 } sort(qu+1,qu+n+1,cmp2); for(int i=1;i<=n;i++) { ans[qu[i].id]=query(qu[i].r); update(qu[i].r); } for(int i=1;i<=n;i++) { printf("%d\n",ans[i]); } return 0; }