解题思路:
实质是排序后求逆序对
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#define ll long long
using namespace std;
const int MAXN = 100000 + 10;
struct Node
{
int l, r;
int id;
bool operator < (const Node& rhs)const
{
if(l != rhs.l)
return l < rhs.l;
else
return r > rhs.r;
}
}cow[MAXN];
struct Tree
{
int l, r;
int sum;
}tree[MAXN<<2];
int ans[MAXN];
void build(int l, int r, int rt)
{
tree[rt].l = l;
tree[rt].r = r;
tree[rt].sum = 0;
if(l == r) return ;
int m = (l + r) >> 1;
build(l, m, rt<<1);
build(m + 1, r, rt<<1|1);
}
void update(int p, int rt)
{
tree[rt].sum ++;
if(tree[rt].l == tree[rt].r) return ;
else
{
int m = (tree[rt].l + tree[rt].r) >> 1;
if(p <= m) update(p, rt<<1);
else update(p, rt<<1|1);
}
}
int Query(int l, int r, int rt)
{
if(tree[rt].l >= l && tree[rt].r <= r)
return tree[rt].sum;
else
{
int m = (tree[rt].l + tree[rt].r) >> 1;
int sum = 0;
if(l <= m) sum += Query(l, r, rt<<1);
if(r > m) sum += Query(l, r, rt<<1|1);
return sum;
}
}
int main()
{
int n;
while(scanf("%d", &n)!=EOF)
{
if(n == 0)
break;
for(int i=0;i<n;i++)
{
scanf("%d%d", &cow[i].l, &cow[i].r);
cow[i].id = i;
}
sort(cow, cow + n);
build(0, MAXN, 1);
for(int i=0;i<n;i++)
{
if(i != 0 && cow[i].l == cow[i-1].l && cow[i].r == cow[i-1].r)
ans[cow[i].id] = ans[cow[i-1].id];
else
ans[cow[i].id] = Query(cow[i].r, MAXN, 1);
update(cow[i].r, 1);
}
for(int i=0;i<n-1;i++)
printf("%d ", ans[i]);
printf("%d\n", ans[n-1]);
}
return 0;
}