题意:给定每个星星(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;
}