洛谷P4135 【作诗】 题解

博客详细分析了一道算法题,题目要求在线求解区间内出现正偶数次数的个数。由于数据范围限制,博主采用分块策略来解决,通过预处理cnt和ans数组,并根据块的左右端点处理询问操作,实现了在线求解。代码实现包括对数组的前缀和处理以及暴力询问策略。
摘要由CSDN通过智能技术生成

题目分析:

首先给出一段序列,共 m 次询问,每一次询问求出给定区间内出现正偶数次数的个数。

算法讲解:

首先,如果忽略本题强制在线的话,可以用莫队来做。

但是,题目中已经规定了需要强制在线来做,于是只能另求他法。

看到数据范围,再结合一下题意,这道题可以用分块来做。

首先,定义两个数组cnt[i][j]表示前i块中j出现的次数ans[i][j]表示第i到第j个块中,出现偶数次数的个数。

这两个数组需要先预处理出来,先来看cnt数组。

相当于一个前缀和的思想,先输入把每一个数+1,然后依次枚举块,把前一块中这个数的出现次数加起来。

for(re int i(1) ; i<=n ; ++i){
    a[i] = read();
    pos[i] = (i-1)/blocksize+1;
    cnt[pos[i]][a[i]]++;
}
for(re int i(1) ; i<=tot ; ++i){
    for(re int j(0) ; j<=c ; ++j){
        cnt[i][j] += cnt[i-1][j];
    }
}

然后来看ans数组。

先枚举每一个块,枚举右端点,让ans[i][j]=ans[i][j−1]作为初始值,往后枚举块j的右端点,可以用一个桶来记录出现次数,具体看代码。

for(re int i(1) ; i<=tot ; ++i){
    for(re int j(i) ; j<=tot ; ++j){
        ans[i][j] = ans[i][j-1]; //赋值
        for(re int k(l[j]) ; k<=r[j] ; +
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值