CodeForces 652D Nested Segments 树状数组

题意:
给你n个区间,问第i个区间有多少个子区间?
分析:
跟poj2481那题差不多,把区间看成是一个点,那么一个区间的子区间一定在它的右下方,即x比他的大,y比他的小的点。然后用树状数组搞下就好,因为题目范围是( - 1e9≤ li < ri ≤ 1e9) ,所以要离散化,因为每个区间的右端点都不一样,所以直接对y排序后离散化就可以。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=2e5+5;
struct point
{
    int x,y,id;
}p[N];
bool cmp1(const point &a,const point &b){return a.y<b.y;}
bool cmp(const point &a,const point &b)
{
    if(a.x==b.x)return a.y<b.y;
    return a.x>b.x;
}
int c[N],ans[N];
int lowbit(int x){return x&(-x);}
int getsum(int x)
{
    int sum =0;
    for(int i=x;i>0;i-=lowbit(i))sum+=c[i];
    return sum;
}
void add(int x)
{
    for(int i=x;i<N;i+=lowbit(i))c[i]++;
}
int main()
{
    int n,x,y;
    scanf("%d",&n);
    for(int i=0;i<n;i++){
        scanf("%d%d",&p[i].x,&p[i].y);
        p[i].id=i;
    }
    sort(p,p+n,cmp1);
    for(int i=0;i<n;i++)p[i].y=i+1;
    sort(p,p+n,cmp);
    for(int i=0;i<n;i++){
        ans[p[i].id]=getsum(p[i].y);
        add(p[i].y);
    }
    for(int i=0;i<n;i++)
        printf("%d\n",ans[i]);
    return 0;
}

你可能感兴趣的:(codeforces)