C++题解:棋子等级

 

目录

题目 

输入格式

输出格式

题解:

知识点:

分析:

代码:


题目 

坐标系平面上有好多棋子,每个整点上至多有一个棋子。

假定棋子的等级是左下方的棋子个数,现在给出若干棋子的位置,求不同等级的棋子各有多少个。左下方包含正下和正左。说明(0, 0) 坐标的位置在左下角。

输入格式

第一行一个整数 N (1≤N≤100000)

接下来 N 行,一行两个整数 X,Y (0≤X,Y<100000),表示坐标。

数据保证坐标先按 Y 排序,再按 X 排序。

输出格式

N 行,每行一个整数,从 0 到 N−1 等级的棋子数量。

样例输入

5
1 1
5 1
7 1
3 3
5 5

样例输出

1
2
1
1
0



题解:

知识点:

树状数组

分析:

我们先将坐标系压成坐标轴(黑笔表坐标和权值,蓝笔表题目输入的顺序):

那么这就显然易见了。题目保证 先按 Y 排序,再按 X 排序,故每当题目输入一对坐标,其对应的横坐标就会在我们压缩成的坐标轴上显示出来(我们这里是一行一行的处理,而不是一整组的处理!),则这个点的权值(答案)就是目前显示出来的其左边的棋子数量(之后显示出来的棋子不能算进去哦~不懂话就画流程图)。故可用树状数组维护。每次update的是1。核心代码:

cnt[getsum(++x)]++;//树状数组的下标从1开始,cnt是计数器
update(x);//更新

 

代码:

#include<iostream>
using namespace std;
const int N=1e5+5;
int n,C[N];
int cnt[N];
inline void c_plus(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
}
inline int lowbit(int x){
    return x&-x;
}
int getsum(int x){
    int res=0;
    for (int i=x;i>0;i-=lowbit(i)){
        res+=C[i];
    }
    return res;
}
void update(int x){
    for (int i=x;i<=N;i+=lowbit(i)){
        C[i]++;
    }
}
int main(){
    c_plus();
    cin>>n;
    for (int i=0;i<n;i++){
        int x,y;
        cin>>x>>y;
        cnt[getsum(++x)]++;//树状数组的下标从1开始
        update(x);//更新
    }
    for (int i=0;i<n;i++){
        cout<<cnt[i]<<endl;
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值