题目大意:
在一个平面上给n个节点。
每一个节点的level为其左下方的节点个数(即xi >= xj, yi >= yj)
求level为0、1、2、3.....、n-2、n-1的节点分别有多少个
(因为坐标有0,所以所有的横坐标都加一,否则可能进入死循环)
这一题最首先的想法是用二维树状数组,可是空间复杂度太大。
因为问题是求左下方的节点数量,所以可以改用一维树状数组维护和查询。
现将节点按照 “y小的小,若y相等则x小的小” 进行从小到大排序。(这一题直接保证了)
然后一次对排序后的节点进行操作
查询每个点的level,直接用树状数组统计 h[1] + h[2] + h[3] + ...... + h[a[i].x] 的合
然后进行更新,h[a[i].x] ++;
我的代码:
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <string.h>
using namespace std;
const int MAXN = 4E4;
int h[MAXN];
int cnt[MAXN];
int n;
int lowbit(int x)
{
return x & (-x);
}
void updata(int x, int val)
{
while (x < MAXN)
{
h[x] += val;
x += lowbit(x);
}
}
int query(int x)
{
int ans = 0;
while (x > 0)
{
ans += h[x];
x -= lowbit(x);
}
return ans;
}
int main()
{
int i, ans, x, y;
memset(h, 0, sizeof(h));
memset(cnt, 0, sizeof(cnt));
scanf("%d",&n);
for (i=1; i<=n; i++)
{
scanf("%d%d",&x,&y);
x ++;
ans = query(x);
updata(x, 1);
cnt[ans] ++;
}
for (i=0; i<n; i++)
printf("%d\n", cnt[i]);
return 0;
}