前缀和问题

1 篇文章 0 订阅

题大意:给你n个数和一个k,问有多少个区间可以得到sum%k==0,比如(l,r),(a[l]+a[l+1]+........+a[r])%k==0

解法:

利用前缀和保存得到前缀和数组,并用一个数组记录下此时前缀和出现的次数,因为当重复出现同一个前缀和的时候代表有一段区间能够%k==0。

代码:

#include <math.h>
#include <algorithm>
#include <iostream>
#include <queue>
#include <cstring>
#include <cstdio>
#include <list>
#include <deque>
#include <set>
#include <vector>
#include <map>
#define LL long long
#define max(a,b) (a>b?a:b)
using namespace std;
const int MAXN=1e6+7;
LL a[MAXN];
LL sum[MAXN]={0};
LL vis[MAXN];
int main()
{
    ios::sync_with_stdio(false);
    LL n,k;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    cin>>k;
    int ans=0;
    for(int i=1;i<=n;i++)
    {
        sum[i]=(a[i]+sum[i-1])%k;
    }
    for(int i=1;i<=n;i++)
    {
        ans+=vis[sum[i]];
        vis[sum[i]]++;
       // cout<<"sum= "<<sum[i]<<endl;
        //cout<<"vis= "<<vis[sum[i]]<<endl;

    }
    cout<<ans<<endl;

    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值