NKOI 1908 星

【线段树】星

Time Limit:10000MS  Memory Limit:65536K
Total Submit:125 Accepted:90

Case Time Limit:1000MS

Description

宇航员经常检测星图,在星图上,星星由点表示而且每颗星星都有笛卡尔坐标。星星的等级表示左下方(包含正左和正下方)星星的数量。宇航员想知道星星等级的分布。

例如,如上面图形所示,第5号星等级是3 (它由三个标记为1,2和4的星组成)。在此地图上,0等级的星星只有一个(1号),1等级的有两个(2和4号),2等级的有一个(3号),3等级的有一个(5号)。
你设计一个程序,在给定地图上计算出每个等级星星的数量。

Input

第一行包含N个星星(1<=N<=200000), 接下来的N行描绘星星的坐标(每行中有两个整数X和Y,由空格分开, 0<=X,Y<=32000)。 在图上的一点只能存在一颗星星,星星根据Y坐标的递增顺序排列,Y坐标相同的星星根据X坐标的递增顺序排列。

Output

包含N 行,一行一个数字,第一行包含0等级星星的数量,第二行包含1等级星星的数量,等等,最后一行包含N-1等级星星的数量。

Sample Input

5                                      
1 1                                    
5 1                                    
7 1                                    
3 3                                    
5 5

Sample Output

1

2

1

1

0


1.我们可以先按y坐标由小到大排序,若两颗星星y相同,则按x坐标由小到大排序。
2.因为题目给出的数据范围是0<=x,y<=32000,所以我们相当于有了一个A数组,下标范围是0到32000,其中A[i]记录的是x坐标为i的星星的颗数。
    那么,对于树状数组而言,C[i]= A[i–2k+ 1] + … + A[i],相当于记录了x坐标在[i-2k+1,i]这段区间中的星星的颗数。
3.按排序后的顺序,从左往右依次讨论每颗星星:
     当讨论到坐标为(p,q)的星星时,只需查询区间[0,q]中星星的颗数就行了。因为前面讨论过的所有星星的y坐标都不会大于q。
     查询完成后,再把该星星插入到树状数组中,即更新C数组中,所有包含了A[p]的元素的值。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn1 200005
#define maxn2 32005
#define lowbit(x) (x&(-x))
int ans[maxn1],a[maxn1],c[maxn1],maxx=-1;
void _read(int &x){
    char tt=getchar();
    while(tt<'0'||'9'<tt) tt=getchar();
    for(x=0;'0'<=tt&&tt<='9';x=x*10+tt-'0',tt=getchar());
}
int getsum(int x){
    int s;
	for(s=0;x;x-=lowbit(x))s+=c[x];
	return s;
}
int main(){
	int i,j,t,n;
    _read(n);
    for(i=1,t;i<=n;i++){
        _read(a[i]);_read(t);
        a[i]++;
        maxx=max(maxx,a[i]);
    }
    for(i=1;i<=n;i++){
        t=getsum(a[i]);
        ans[t]++;
        for(j=a[i];j<=maxx;j+=lowbit(j))c[j]++;
    }
    for(i=0;i<n;i++)
        printf("%d\n",ans[i]);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值