一本通.1536数星星 Stars(树状数组)
Posted SSL_LKJ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一本通.1536数星星 Stars(树状数组)相关的知识,希望对你有一定的参考价值。
数星星 Stars
题目传送门
【题目描述】
原题来自:Ural 1028
天空中有一些星星,这些星星都在不同的位置,每个星星有个坐标。如果一个星星的左下方(包含正左和正下)有 k
颗星星,就说这颗星星是 k级的。
例如,上图中星星 5
是 3 级的(1,2,4 在它左下),星星 2,4 是 1 级的。例图中有 1 个 0 级,2 个 1 级,1 个 2 级,1 个 3
级的星星。
给定星星的位置,输出各级星星的数目。
一句话题意:给定 n个点,定义每个点的等级是在该点左下方(含正左、正下)的点的数目,试统计每个等级有多少个点。
【输入】
第一行一个整数 N,表示星星的数目;
接下来 N行给出每颗星星的坐标,坐标用两个整数 x,y表示;
不会有星星重叠。星星按 y坐标增序给出,y 坐标相同的按 x坐标增序给出。
【输出】
N行,每行一个整数,分别是 0 级,1 级,2 级,……,N−1级的星星的数目。
【输入样例】
5
1 1
5 1
7 1
3 3
5 5
【输出样例】
1
2
1
1
0
【提示】
数据范围与提示:
对于全部数据,1≤N≤1.5×104,0≤x,y≤3.2×104。
解题思路
对于每个星星按y坐标从小到大排序,相同y坐标按x坐标从小到大排序。输入顺序已排好序,那么只要依次统计星星i之前x坐标小于等于i.x的星星有多少,即是星星i的级别。y坐标没用,显然是一维树状数组应用。
设数组a[x]初始为0,表示在x坐标处星星的个数,则求和a[0] ~ a[x]则为该星星的等级。
有一个地方尤其要注意,树状数组是以1号为起始的,而且只能用1号。x可能为0,为0会时陷入死循环,处理时要将所有的x+1。
还有就是x的范围不能事先确定,在update的时候直接加到x取值范围的最大值,即32001,或者在输入的时候找一个x的最大值。
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int n,x,y,s,a[32005],b[32005];
int cx(int x)//查询
s=0;//初值
for(;x;x-=x&(-x))s+=a[x];//累加区间的值
return s;//返回
void update(int x,int y)//更改
for(;x<=32001;x+=x&(-x))a[x]+=y;//更改
int main()
scanf("%d",&n);//用scanf和printf,免得超时
for(int i=1;i<=n;i++)
scanf("%d%d",&x,&y);
b[cx(x+1)]++;//累加
update(x+1,1);//更改
for(int i=1;i<=n;i++)
printf("%d\\n",b[i-1]);
谢谢
以上是关于一本通.1536数星星 Stars(树状数组)的主要内容,如果未能解决你的问题,请参考以下文章