1144 數星星
該題有題解
時間限制:564MS 內存限制:65536K
提交次數:193 通過次數:43
題型: 編程題 語言: G++;GCC
Description
天文學家們喜歡觀察星星。它們把每顆星星看成一個點,並把每顆星星左下方(即橫座標和縱座標都不比它大)的星星顆數作爲它的等級值。 現給出所有星星(星星個數爲N)的座標,計算並輸出指定編號的星星的等級。 注意:不存在相同座標的星星
輸入格式
第一行爲N 後N行爲編號爲1到N的星星的座標(座標用整數) 此後是M 後一行是M個星星的編號 N<=100000 M<=1000 座標範圍0<=x,y<=1000000
輸出格式
要求依次輸出這M個星星的等級,一行一個
輸入樣例
5 0 0 2 0 3 0 1 1 2 2 2 4 5
輸出樣例
1 3 該題爲poj上star的變形,也沒變多少。求一個星星的等級,也就是求該星星的下面和左面一共有多少個星星。可以現將所有星星的按座標排序,按y軸先排或者按x軸先排都可以。 若按Y軸排好序後,我們只需要知道該所求星星的左邊有多少個星星就行了,也就是有多少個x比它小的。 這樣,求之前所有的x,問題就轉化爲求數列的前綴和,我們可以用樹狀數組去解決。 下面是一些關於樹狀數組的博客 http://www.cnblogs.com/huangxincheng/archive/2012/12/05/2802858.html http://blog.chinaunix.net/uid-22263887-id-1778936.html http://www.cnblogs.com/zhj5chengfeng/archive/2013/03/20/2965833.html http://www.cnblogs.com/Hilda/archive/2012/08/08/2628426.html https://www.topcoder.com/community/data-science/data-science-tutorials/binary-indexed-trees/#prob 題目代碼如下:由於要將星星排序,而排序後又要按原來的下標找到它的位置,可以設置一個結構體 struct bit{ int x,y,z; }; x,y存儲座標,而z存儲它在原來序列的座標。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define maxn 1000005
using namespace std;
int c[maxn],maxx;
struct BIT{
int x,y,z;
}bit[maxn];
bool cmp(BIT a, BIT b)
{
if( a.y == b.y)
return a.x < b.x;
return a.y < b.y;
}
int lowbit(int i)
{
return i&(-i);
}
int sum(int i)
{
int ans = 0;
{
while(i)
{
ans += c[i];
i -= lowbit(i);
}
}
return ans;
}
void update(int i,int newValue)
{
while(i<=maxx)
{
c[i] += newValue;
i += lowbit(i);
}
}
int t[maxn], cnt[maxn];
int main()
{
//freopen("a","r",stdin);
int n, m;
memset(c,0,sizeof(c));
maxx = 0;
scanf("%d", &n);
for(int i=0; i<n; i++)
{
scanf("%d%d", &bit[i].x,&bit[i].y);
bit[i].x++;
bit[i].y++;
bit[i].z = i;
if(maxx < bit[i].x)
maxx = bit[i].x;
}
sort(bit,bit+n,cmp);
for(int i=0; i<n; i++)
{
cnt[bit[i].z] = sum(bit[i].x);
update(bit[i].x,1);
}
scanf("%d",&m);
for(int i=0; i<m; i++)
{
scanf("%d", &t[i]);
}
for(int i=0; i<m; i++)
{
printf("%d\n", cnt[t[i]-1]);
}
}