You 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.ios
Input數組
The first line contains a single integer n (1 ≤ n ≤ 2·105) — the number of segments on a line.ide
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.spa
Outputcode
Print n lines. The j-th of them should contain the only integer aj — the number of segments contained in the j-th segment.blog
Example排序
4
1 8
2 3
4 7
5 6
3
0
1
0
3
3 4
1 5
2 6
0
1
1
題意:如今X軸上,有N個線段,給出每條線段是左端點和右端點,求每條線段覆蓋了多少其餘的線段。ci
思路:按右端點排序,而後一條一條的歸入考慮。每考慮一條新的,查詢以前考慮過的左端點大於當前左端點的,就是當前線段的答案。而後把當前線段的左端點插入樹狀數組。(由於右端點是有序的,只須要考慮左端點便可,而左端點只須要樹狀數組來維護區間和及查詢)。input
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int maxn=400010; int sum[maxn],a[maxn],ans[maxn],N,tot; struct in { int x; int y; int id; friend bool operator <(in a,in b){ if(a.y==b.y) return a.x>b.x; return a.y<b.y; } }s[maxn]; void add(int x){ while(x<=tot) { sum[x]++; x+=(-x)&x; } } int query(int x){ int res=0; while(x){ res+=sum[x]; x-=(-x)&x; } return res; } int main() { scanf("%d",&N); for(int i=1;i<=N;i++) { scanf("%d%d",&s[i].x,&s[i].y); s[i].id=i; a[++tot]=s[i].x; a[++tot]=s[i].y; } sort(a+1,a+tot+1); tot=unique(a+1,a+tot+1)-(a+1); sort(s+1,s+N+1); for(int i=1;i<=N;i++){ int tx=lower_bound(a+1,a+tot+1,s[i].x)-a; int ty=lower_bound(a+1,a+tot+1,s[i].y)-a; ans[s[i].id]=query(ty)-query(tx-1); add(tx); } for(int i=1;i<=N;i++) printf("%d\n",ans[i]); return 0; }