Live2d Test Env

CodeForces-652D:Nested Segments(树状数组+离散化)

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.

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.

Example

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

题意:现在X轴上,有N个线段,给出每条线段是左端点和右端点,求每条线段覆盖了多少其他的线段。

思路:按右端点排序,然后一条一条的纳入考虑。每考虑一条新的,查询之前考虑过的左端点大于当前左端点的,就是当前线段的答案。然后把当前线段的左端点插入树状数组。(因为右端点是有序的,只需要考虑左端点即可,而左端点只需要树状数组来维护区间和及查询)。

#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;
}

 

posted @ 2018-03-15 21:09  nimphy  阅读(392)  评论(2编辑  收藏  举报