http://codeforces.com/contest/652/problem/D
题意,给n个区间(端点保证不重复)
输出每个区间包含了多少个区间
先存起所有区间的左右端点,并依次对应编号
然后把左右端点 分别从小到大排序
并开一个树状数组,每个点对应着Yi,初始化值全为1
从小到大遍历左端点,
对于X1,找到其原始编号id,然后再找出对应的Y
然后在排序后的Y数组里 二分找到 Y的位置,那么 当前id的左端点是最左的,所有区间的左端点都在X1的后面,必然 当前区间可以把Y左边的所有区间都包含。
【因为当前区间左端点最左,所以不会还有区间能包含它,因此把点Y在树状数组里挖掉】
求答案的话 就是在树状数组的1到Y-1 里面的节点个数,然后把Y这个节点挖掉,继续遍历左端点
每次求树状数组里1到Y-1的和,然后把 Y挖掉
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
int ll[2*100005];
int rr[2*100005];
int sort_r[2*100005];
int min(int a,int b)
{return a<b?a:b;}
int tree[2*100005];
int n;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int value)
{
for (int i=x;i<=n;i=i+lowbit(i))
{
tree[i]+=value;
}
}
int get(int x)
{
int sum=0;
for (int i=x;i;i-=lowbit(i))
{
sum+=tree[i];
}
return sum;
}
struct node
{
int x,y,id;
};
node tm[2*100005];
bool cmp(node a,node b)
{return a.x<b.x;}
int ans[2*100005];
int main()
{
int i;
cin>>n;
for (i=1;i<=n;i++)
{
scanf("%d%d",&tm[i].x,&tm[i].y);
ll[i]=tm[i].x;
rr[i]=tm[i].y;
sort_r[i]=rr[i];
tm[i].id=i;
add(i,1);
}
sort(tm+1,tm+1+n,cmp);
sort(sort_r+1,sort_r+1+n);
for (i=1;i<=n;i++)
{
int id=tm[i].id;
int yy=rr[id];
int it=lower_bound(sort_r+1,sort_r+1+n,yy)-sort_r;
int res=0;
if (it==1) res=0;
else res=get(it-1);
ans[id]=res;
add(it,-1);
}
for(i=1;i<=n;i++)
{
printf("%d\n",ans[i]);
}
return 0;
}