zcmu--1907(前缀和)

问题 E: k倍区间

时间限制: 1 Sec  内存限制: 128 MB
提交: 145  解决: 44
[提交][状态][讨论版]

题目描述

给定一个长度为N的数列,A1, A2, ... AN,如果其中一段连续的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍数,我们就称这个区间[i, j]是K倍区间。

你能求出数列中总共有多少个K倍区间吗?

输入

每个数据包含多组输入数据

第一行包含两个整数N和K。(1 <= N, K <= 100000) 
以下N行每行包含一个整数Ai。(1 <= Ai <= 100000)

输出

输出一个整数,代表K倍区间的数目。

样例输入

5

2 1 2 3 4 5

样例输出

6

提示

[提交][状态][讨论版]

思路:一开始想查找长度是1,2~n的子串,然后求和,但是时间复杂度是n^3,超时

后来想将每一项都变为前i项的和,复杂度变为n^2,但还是超时,

如果第i项对k取余的得到的数相同就说明它们相减可以整除k,复杂度为n,所以利用前缀和来求解为最佳方案(记住要最后加上对k取余结果为0的数的个数,它们本身就符合条件)。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int a[100100],b[100100],c[100100];
int main(void)
{
    int n,k,i,j,res;
    while(~scanf("%d %d",&n,&k))
    {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        memset(c,0,sizeof(c));
        res=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=b[i-1]+a[i];
            int tp=b[i]%k;
            res+=c[tp];
            c[tp]++;
        }
        printf("%d\n",c[0]+res);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/82751545