题意:定义在某颗星星左下方的星星的个数表示该星星的水平,求出水平分别为为0...n-1的星星个数。
首先题目是按照y坐标升序输入的,设第第1,2...n个星星的横坐标依次为x1,x2,...xn.显然星星i的level等于(x1,x3,...xi-1)中比xi小的数的个数,将它记做Li,普通求法扫描一遍,
复杂度为O(n^2),显然数据了大会超时。采用树状数组来解决,复杂度为O(nlogn),用a[x]表示横坐标为x的点的个数,随着输入,不断更新维护树状数组。
#define _CRT_SECURE_NO_DEPRECATE #include<iostream> using namespace std; const int MAXN = 32100; /*tree为树状数组,ans数组统计星星水平*/ int tree[MAXN],ans[MAXN]; int n; int readSum(int k){ //求和a[1]+a[2]...+a[k] int sum = 0; while (k > 0){ sum += tree[k]; k -= (k&-k); } return sum; } void add(int pos, int diff){ //增量修改 while (pos <MAXN){ tree[pos] += diff; pos += (pos&-pos); } } int main(){ int i, x, y; while (scanf("%d", &n) != EOF){ memset(ans, 0, sizeof(ans)); memset(tree, 0, sizeof(tree)); for (i = 0; i < n; i++){ scanf("%d%d", &x, &y); x++; //避免0带来的不便 int level = readSum(x); //计算星星的水平 ans[level]++; add(x, 1); //维护树状数组 } for (i = 0; i < n; i++){ printf("%d\n", ans[i]); } } return 0; }
时间: 2024-11-05 11:47:14