Code Forces 652D Nested Segments(离散化+树状数组)
Nested Segments
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
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
离散化+树状数组。
把所有区间按照右端点排序,然后统计左端点和右端点之间的已经包含的左端点个数,用树状数组求区间和会很快
#include <iostream> #include <string.h> #include <stdlib.h> #include <algorithm> #include <stdio.h> #include <math.h> using namespace std; #define MAX 2*100000 struct Node { int l,r; int pos; }a[MAX+5]; int n; int num[2*MAX+5]; int c[2*MAX+5]; int ans[MAX+5]; int s; int lowbit(int x) { return x&(-x); } void update(int x,int num) { while(x<=s) { c[x]+=num; x+=lowbit(x); } } int sum(int x) { int _sum=0; while(x>0) { _sum+=c[x]; x-=lowbit(x); } return _sum; } int cmp(Node a,Node b) { return a.r<b.r; } int main() { scanf("%d",&n); memset(c,0,sizeof(c)); int cnt=0; for(int i=1;i<=n;i++) { scanf("%d%d",&a[i].l,&a[i].r); a[i].pos=i; num[cnt++]=a[i].l; num[cnt++]=a[i].r; } sort(num,num+cnt); for(int i=1;i<=n;i++) { a[i].l=lower_bound(num,num+cnt,a[i].l)-num+1; a[i].r=lower_bound(num,num+cnt,a[i].r)-num+1; } sort(a+1,a+n+1,cmp); s=a[n].r; for(int i=1;i<=n;i++) { int num=sum(a[i].r)-sum(a[i].l-1); ans[a[i].pos]=num; update(a[i].l,1); } for(int i=1;i<=n;i++) { printf("%d\n",ans[i]); } return 0; }