题意:
给你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
",ans[i]);
return 0;
}