这道题本是很简单的一道题目,题意是统计一个平面坐标系中某点左下方有多少个点,做的时候却卡了三个地方。
第一个:统计什么?
树状数组的作用就是统计[x,y]这个区间的和,至于这个区间里面是什么,就因题而异了。这里数星星,要找到有多少个星星x和y都小于待求的那个点,y是从小到大排的,所以,只需要统计前面到底有多少个x是比现在这个小的。
第二个:被统计值的定义域
树状数组的大小和被统计值得取值范围一样大,本题如果离散化的话会减小x的取值范围。
第三个:树状数组可以统计的值不包括0
如果包含0的话要把坐标整体平移一位。
#include<stdio.h>
#include<string.h>
int lowbit(int x)
{
return x&(-x);
}
int n;
int MAX_N=32022;
int bit[40000];
int ans[20000];
int sum(int i)
{
int s=0;
while(i>0)
{
s+=bit[i];
i-=(i&(-i));
}
return s;
}
void add(int i,int x)
{
while(i<MAX_N)
{
bit[i]+=x;
i+=(i&(-i));
}
}
int Scan()
{
int res = 0, ch, flag = 0;
if((ch = getchar()) == '-') //判断正负
flag = 1;
else if(ch >= '0' && ch <= '9') //得到完整的数
res = ch - '0';
while((ch = getchar()) >= '0' && ch <= '9' )
res = res * 10 + ch - '0';
return flag ? -res : res;
}
int nextInt(){
int ret = 0;
char ch = getchar();
while(ch > '9' || ch < '0')
ch = getchar();
ret = ch - '0';
ch = getchar();
while(ch <= '9' && ch >= '0'){
ret = ret * 10 + ch - '0';
ch = getchar();
}
return ret;
}
int main()
{
while(scanf("%d",&n)!=EOF){
memset(bit,0,sizeof(bit));
memset(ans,0,sizeof(ans));
int x,y;
for(int i=1;i<=n;i++)
{
x=nextInt();
y=nextInt();
// scanf("%d%d",&x,&y);
x++;
ans[sum(x)]++;
add(x,1);
}
for(int i=0;i<=n-1;i++)
{
printf("%d\n",ans[i]);
}
}
return 0;
}
两个输入挂,可有可无,是拿来实验的,比普通的scanf快了100ms,也挺多的。不过一般用不到。