codeforces 652D D. Nested Segments(离散化+sort+树状数组)

题目链接:

D. Nested Segments

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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.

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

 

 

posted @ 2016-03-26 13:18  LittlePointer  阅读(585)  评论(1编辑  收藏  举报