树状数组BIT(Binary index tree)
对于树状数组而要我们可以发现树状数组的那个图就是线段树的去掉所有右孩子节点得到的,因此树状数组相当于在线段树上做了一个优化,相当于去掉了一个常数,并且空间上也进行了优化,线段树通常需要比原来大小开4倍,但是树状数组就不用,但是树状数组只提供2种操作,一个就是询问1到x的所有数的和,另一个就是对单点进行更新,其他操作较为复杂。
操作一
int sum(int x){
int res = 0;
while(x){
res += bit[x];
x -= x&-x;
}
return res;
}
操作二
void add(int x, int y){
while(x <= maxn){
bit[x] += y;
x += x&-x;
}
}
本题分析
因为Y坐标是单点递增的,所以对于只需要统计其他所有点X坐标小于或者等于X的个数,然后进行更新即可。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 32050;
int bit[maxn], vis[maxn], N;
int sum(int x){
int res = 0;
while(x){
res += bit[x];
x -= x&-x;
}
return res;
}
void add(int x, int y){
while(x <= maxn){
bit[x] += y;
x += x&-x;
}
}
int main(){
while(scanf("%d", &N) != EOF){
memset(bit, 0, sizeof(bit));
memset(vis, 0, sizeof(vis));
int x, y;
for(int i = 0; i < N; i++){
scanf("%d%d", &x, &y);
++x;
vis[sum(x)]++;
add(x, 1);
}
for(int i = 0; i < N; i++) printf("%d\n", vis[i]);
}
return 0;
}