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.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排序

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個線段,給出每條線段是左端點和右端點,求每條線段覆蓋了多少其餘的線段。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;
}
相關文章
相關標籤/搜索