蓝桥杯2017年第八届真题-k倍区间

#蓝桥杯2017年第八届真题-k倍区间**

题目:

在这里插入图片描述

思路:

区间和可以看作是前缀和的差
a r r [ l , r ] = S [ r ] − S [ r − l − 1 ] arr[l,r]=S[r]-S[r-l-1] arr[l,r]=S[r]S[rl1]
那么问题就转换成的有多少对前缀和的差能够整除k
S [ r ] − S [ r − l − 1 ] ≡ 0 ( m o d k ) S[r]-S[r-l-1]≡0(mod k) S[r]S[rl1]0(modk)

S [ r ] ( m o d ) k − S [ r − l − 1 ] ( m o d ) k ≡ 0 S[r](mod)k-S[r-l-1](mod)k≡0 S[r](mod)kS[rl1](mod)k0

S [ r ] ( m o d ) k ≡ S [ r − l − 1 ] ( m o d ) k S[r](mod)k≡S[r-l-1](mod)k S[r](mod)kS[rl1](mod)k

所以题目就拆分成为找多少对前缀和的值对 k k k取余是一样的 ,最后再加上单独取余 k k k 0 0 0的个数,因为我们前面求的是两两一组相减的 k k k倍区间,单独的 k k k倍区间没有算进去

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define MAX 500100
int main()
{
    ll sum[MAX];//前缀和对k取余的值
    ll hashmap[MAX];//余数的值出现的次数

    ll n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++) {
        int a;
        cin>>a;
        sum[i]=(sum[i-1]+a)%k;
    }
    ll cont=0;
    for(int i=1;i<=n;i++){
        cont+=hashmap[sum[i]];//判断在这之前有多少对(mod)k值一样的前缀
        hashmap[sum[i]]++;
    }
    cont+=hashmap[0];//最后加上单独k倍的次数
    
    cout<<cont<<endl;
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值