poj2352 - Stars(树状数组)
题意:给定每个星星(x,y)的坐标求该满足条件(x'<=x&&y'<=y)的已存在的星星(x', y')的个数。
思路:题目的输入数据很有特色就是按行输入,
例如:
5
0 1
5 1
7 1
3 3
5 5
就是第一行的3个坐标优先,然后是第二行的,然后是。。。。。
所以我们求满足条件的星星数目便无须关心纵坐标了。
可以直接用线段树写出来,也可以离散化后在写出来,总之要注意x=0的情况,
离散化的时候由于排序失误还wa了一次。
原因是排序过程如果不规定原序作为次级排序依据的话,最后出来的结果很可能会出现相等数字的顺序跟原序不同的状况;
离散化代码:
#include <cstdio> #include <algorithm> using namespace std; #define M 15005 #define lowbit(x) -x&x struct Node{ int v, x; }; Node a[M]; int n, c[M], r[M], ans[M]; int comp(const Node p, const Node q) { return p.v==q.v?p.x<q.x:p.v<q.v; } void add(int x) { while(x<=n) { c[x]+=1; x+=lowbit(x); } } int sum(int x) { int ret = 0; while(x>0) { ret+=c[x]; x-=lowbit(x); } return ret; } int main () { int t; scanf("%d",&n); for(int i = 1; i <= n; ++i) { scanf("%d %*d",&t); a[i].v = t; a[i].x = i; } sort(a+1,a+n+1,comp); for(int i = 1; i <= n; ++i) r[a[i].x] = i; for(int i = 1; i <= n; ++i) { ++ans[sum(r[i])]; add(r[i]); } for(int i = 0; i < n; i++) printf("%d\n",ans[i]); return 0; }
未离散化代码:
#include <cstdio> #define M 15005 #define N 32005 #define lowbit(x) -x&x int n, c[N], ans[M]; void add(int x) { while(x<=32004) { c[x]+=1; x+=lowbit(x); } } int sum(int x) { int ret = 0; while(x>0) { ret+=c[x]; x-=lowbit(x); } return ret; } int main () { int t; scanf("%d",&n); for(int i = 1; i <= n; ++i) { scanf("%d %*d",&t); ++ans[sum(t+1)]; add(t+1); } for(int i = 0; i < n; i++) printf("%d\n",ans[i]); return 0; }