题目
这两个题出题思路一样。不一样的地方在于 Stars 的数据范围是
1−15000,0−32000
1
−
15000
,
0
−
32000
,而约定的数据范围是
1−100000,1−100000
1
−
100000
,
1
−
100000
.即使是这样,POJ 的题花了我
344ms
344
m
s
跑过去,而UESTC只用了
64ms
64
m
s
。这是两张图片。为什么这张图上园子这么帅!不科学。
题目翻译一下,平面直角坐标系第一象限或者坐标轴上有n个点,定义一个点的等级(level,rank)为横坐标纵坐标均不大于它的点的个数。输出level分别为0 to n-1的点的个数。
题解
昨天打的树状数组模板马上就可以用了。x和y都是影响答案的内容,我们先对x排序,这样接下来我们就不用管横坐标,只要前者的纵坐标小于等于后者,后者的等级就+1.
struct enemy{int x,y;}vertex[boss+10];
inline bool cmp(enemy a,enemy b){return a.x!=b.x?a.x<b.x:a.y<b.y;}
接下来我们只要按顺序枚举每一个点的纵坐标,设数组dengji[i]为等级为i的点的个数,用树状数组实时优化就可以了。注意UESTC1584的题解不能直接交到POJ上去,要做修改。(数据范围中有0)我也不知道为什么我直接交到POJ上会TLE.
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define lowbit(x) (x&-x)
using namespace std;
const int boss=1e5;
struct enemy{int x,y;}vertex[boss+10];
inline bool cmp(enemy a,enemy b){return a.x!=b.x?a.x<b.x:a.y<b.y;}
int dengji[boss+10],c[boss+10],n;
inline int get(int x){int sum=0;for (;x;x-=lowbit(x)) sum+=c[x];return sum;}
inline void add(int x,int y){for (;x<=boss;x+=lowbit(x)) c[x]+=y;}
inline int read()
{
int x=0;char c=getchar();
for (;!isdigit(c);c=getchar());
for (;isdigit(c);c=getchar()) x=x*10+c-'0';
return x;
}
int main()
{
int i;
n=read();
for (i=0;i<n;i++) vertex[i].x=read(),vertex[i].y=read();
sort(vertex,vertex+n,cmp);
for (i=0;i<n;i++) dengji[get(vertex[i].y)]++,add(vertex[i].y,1);//比它纵坐标大的都+1,下一次get的时候就能get到它。
for (i=0;i<n;i++) printf("%d\n",dengji[i]);
}