学树状数组的话,可以看
英文的和
中文的(中文的很多啊,可以自己搜,只不过我觉得这篇比较好)
后来看到有些
blog(这个链接以前弄错了,在此表示不好意思)写到2352是入门题。
表示我一开始不会写,后来是看了人家的思路才写出来的-_-.
用树状数组,不用管y坐标(因为已经是升序,后边的星星不影响前边星星的等级),用level(n)来统计x坐标为n以前的星星个数,但是千万注意树状数组需要数组以1为首项,由于坐标有0,所以每次需要给x坐标+1(因为出现0会死循环)
还有一点就是那篇英文的介绍里面有点小错误,就是scale的第一个函数中,调用update时参数传反了
#include <iostream>
using namespace std;
int tree[32006];
int level[32006];
int n;
void update(int idx)//更新,因为所有的都只会增加1,所以只用传一个参数就行了
{
while(idx <= 32006)
{
tree[idx]++;
idx += (idx & (-idx));
}
}
int read(int idx)
{//求一段数组的和
int sum = 0;
while(idx > 0)
{
sum += tree[idx];
idx -= (idx & (-idx));
}
return sum;
}
int main(void)
{
freopen("2352.in","r",stdin);
freopen("2352.out","w",stdout);
int x,y;
scanf("%d",&n);
memset(tree,0,sizeof(tree));
memset(level,0,sizeof(level));
for(int i = 0;i < n;i++)
{
scanf("%d%d",&x,&y);
x++;//防止出现下标0
level[read(x)]++;//先得到改点的level值
update(x);//更新以x为下标的tree数组值
}
for(int i = 0;i < n;i++)
{
printf("%d\n",level[i]);//不用减1 因为我是先求在更新的
}
return 0;
}