题意:给出N颗星星 每颗星星的位置坐标是Xi,Yi 给出顺序为以坐标Y为第一关键字 升序给出 当Y相同的时候 以X为第二关键字 升序给出 一颗星星的等级 = 它左下的星星个数总和 现让你求出每个等级(0~N-1)的星星一共有多少颗
解题思路:因为星星是以Y为第一关键字以升序的方式给出 所以后给出的星星肯定是在前面星星的上面(或同行左边) 所以只要考虑X的坐标就可以了 如果当前X的坐标大于等于之前已经给出的星星的X的坐标 那么就满足条件 这个星星的level就加一 之后就变成一个求和的过程 这样的话就可以用线段树或树状数组去做了 具体解释看代码
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<map>
#include<set>
#include<queue>
#include<list>
#include<stack>
#include<vector>
#include<math.h>
#include<stdlib.h>
#include<time.h>u
using namespace std;
#define ll __int64
#define mem(a) memset(a,0,sizeof(a))
#define CLR(a, b) memset(a, b, sizeof(a))
#define INF 0x3f3f3f
const int maxn = 15005; //星星个数的最大值
const int size = 32005; //坐标的最大值
int c[size],n; //C数组的下标为就表示X 其值就等于坐标比X小的星星个数有多少个
int ans[maxn]; //下标表示等级 用来记录这个等级的星星个数有多少个
//树状数组
int lowbit(int x){
return x&(-x);
}
void change(int pos,int x){
while(pos <= size){
c[pos] += x;
pos += lowbit(pos);
}
}
int query(int pos){
int sum = 0;
while(pos >= 1){
sum += c[pos];
pos -= lowbit(pos);
}
return sum;
}
int main(){
while(scanf("%d",&n) != EOF){
mem(ans);
mem(c);
for(int i = 1 ;i <= n;i++){
int x,y;
scanf("%d%d",&x,&y); //这边就无需考虑Y了 直接可以用X去判断
ans[query(x+1)]++; // 星星个数求和即为等级
change(x+1,1); //只要坐标比X大的星星等级都加上1
}
for(int i = 0;i < n;i++) printf("%d\n",ans[i]);
}
return 0;
}