专栏文章

B4105 [CSP-X2024 山东] 消灭怪兽 题解

B4105题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miqmr42a
此快照首次捕获于
2025/12/04 07:20
3 个月前
此快照最后确认于
2025/12/04 07:20
3 个月前
查看原文

题意

就是求武器数组 aa 中有多少个区间和是 kk 的倍数。

思路

由于 nn 小于等于 10610^6 所以需要用到前缀和,并且需要优化。
每次计算前缀和时需要对 kk 取模,最后用一个桶(下文 tt)来记录每个前缀和对 kk 取模的余数。
最后把 tt00k1k - 1 遍历,不难看出,tit_i 对答案的贡献是 ti×(ti1)×12t_i \times (t_i - 1) \times \frac{1}{2},如果 tit_i 大于等于二,答案就加上 ti×(ti1)×12t_i \times (t_i - 1) \times \frac{1}{2}
注意nn 小于等于 10610^6
所以:十年 OI 一场空,____________。

Code

CPP
#include <iostream>
#define ll long long
using namespace std;
const int M = 1e6 + 5;
ll a[M], e[M], tong[M];
int main()
{
    ll n, k, cnt = 0;
    cin >> n >> k;
    for(int i = 1; i <= n; i++)
    {
        cin >> a[i];
        e[i] += (e[i - 1] + a[i]) % k;
    }
    tong[0] = 1;
    for(int i = 1; i <= n; i++)
    {
        tong[e[i]]++;
    }
    for(int i = 0; i < k; i++)
    {
        if(tong[i] >= 2)
        {
            cnt += tong[i] * (tong[i] - 1) / 2;
        }
        
    }
    cout << cnt;
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...