一维树状数组的应用
题意:在整数坐标0<=x,y<=32000上有很多星星
每颗星的level(级别)值 等于 不比它高不比它右的星星数目
给出每颗星星的坐标。求每个level的星星数目。
其实大家
算法分析:
好像要所有数据读入之后才一个个问,其实不然,我们可以采取一边读数据一边统计的方法
(注意了,输入格式已经给出:星星按 Y 的升序给出,Y 相等则按 X 的升序给出)。
也是就是当前的第i个星星读入坐标的时候其实它的级别已经确定了,因为后面的星星不会让星星i升级的,
(因为星星是按Y升序给出的,所以后面的星星不会比当前星星i低,最多同高,但因为同高的星星是从左到右给出的,所以后面的星星不会在当前星星i的左边。)
所以我们只需要 关注 每颗星星的x坐标,统计 1~x[i]有多少个值出现过,出现过的点为1,那么我们就可以统计了。
代码:
#include <cstdio>
#include <cstring>
using namespace std;
int c[32010],l[32010],n;
int lowbit(int x)
{
return x&-x;
}
void add(int x,int y)
{
while (x<=32005)
{
c[x]+=y;
x+=lowbit(x);
}
}
int getsum(int x)
{
int s=0;
while (x>=1)
{
s+=c[x];
x-=lowbit(x);
}
return s;
}
int main()
{
int x,y;
while (scanf("%d",&n)!=EOF)
{
memset(c,0,sizeof(c));
memset(l,0,sizeof(l));
for (int i=1;i<=n;i++)
{
scanf("%d%d",&x,&y);
add(x+1,1);
l[getsum(x+1)]++;
}
for (int i=1;i<=n;i++)
printf("%d\n",l[i]);
}
}
stars的拓展:
poj2481 cows
看到这道题,做过的同志们肯定又要偷笑了,没看过的同志们又接着懵逼了
题意:
一条线上有很多不同长度的线段【s,e】,代表了不同牛的领域范围。如果Si <= Sj 并且 Ej <= Ei 并且 Ei - Si > Ej - Sj 就说明母牛i比母牛j强壮。对于每一头牛,有多少头牛比他强壮?
算法分析:
我们可以把这一条线段扩大成一片草地(类似平面直角坐标系的东东),将每头母牛的领域范围线段【s,e】变为一个在平面直角坐标系上的点【s,e】。画一画图,是不是和上面的stars很像咧?只需要变动一下(注意:stars是求他左下方有多少个点,而这一题则是求他的左上方有多少个点)。
值得提醒一下的是:这一题的数据是无序给出的,我们需要预先排序。