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

来源:互联网 发布:昆山编程培训要多久 编辑:程序博客网 时间:2024/05/18 20:09

题意:给你n条线段,保证端点不完全重合,问每条线段包含了多少条线段。

思路:只有最多2e5个线段,所以我们可以先离散化一下。然后将每条线段都按左端点排序,将每个线段的右端点用树状数组维护,那么就可以直接扫一遍,由于左端点已经是有序的了,i+1的线段不会包含i,所以还需要将i线段的右端点删除,当然需要注意的是如果左端点相同,排序的时候要按右端点大的来排序,自己画个图就知道了


#include<bits/stdc++.h>using namespace std;const int maxn = 4e5+100;struct Node{int l,r,id,ans;}se[maxn];int c[maxn];vector<int>v;bool cmp(Node a,Node b){if(a.r==b.r)return a.l<b.l;if(a.l==b.l)return a.r>b.r;return a.l<b.l;}bool cmp1(Node a,Node b){return a.id<b.id;}int getid(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}int lowbit(int x){return x&(-x);}void update(int i,int d){while(i<=maxn){c[i]+=d;i+=lowbit(i);}}int query(int i){int ans = 0;while(i){ans+=c[i];i-=lowbit(i);}return ans;}int main(){    int n;scanf("%d",&n);for(int i = 1;i<=n;i++){scanf("%d%d",&se[i].l,&se[i].r);se[i].id=i;v.push_back(se[i].l),v.push_back(se[i].r);}sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end());    for(int i= 1;i<=n;i++)    se[i].l=getid(se[i].l),se[i].r=getid(se[i].r);sort(se+1,se+1+n,cmp);for(int i = 1;i<=n;i++)update(se[i].r,1);for(int i = 1;i<=n;i++){        se[i].ans = query(se[i].r)-1;update(se[i].r,-1);}sort(se+1,se+1+n,cmp1);for(int i = 1;i<=n;i++)printf("%d\n",se[i].ans);}


Description

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.

Sample Input

Input
41 82 34 75 6
Output
3010
Input
33 41 52 6
Output
011


0 0
原创粉丝点击