ACM: 数论题 toj 1721

                  Partial Sums

描述

 

Given a series of n numbers a1, a2, ..., an, the partial sum of the numbers is defined as the sum of ai, ai+1, ..., aj.

You are supposed to calculate how many partial sums of a given series of numbers could be divided evenly by a given number m.

输入

 

There are multiple test, each contains 2 lines.

The first line is 2 positive integers n (n <= 10000 ) and m (m <= 5000).

The second line contains n non-negative integers a1, a2, ..., an. Numbers are separated by one or several spaces.

The input is ended by EOF.

输出

 

One test each line - the number of partial sums which could be divided by m.

样例输入

5 4
1 2 3 4 5
6 7
9 8 7 6 5 4

样例输出

2
3

 

题意:  求出子序和能够整除m的子序个数.

 

解题思路:

        1. sum[i....j] = sum[1.....j] - sum[1.....(i-1)]  < == > sum[1...j] % m == sum[1...(n-1)] % m

        2. 显然, 它们的求余相同时, 表示即前段相同, 剩下的序列和是可以整除m.

        3. 例如:

                      4

                     1 2 3 4 5

            (1+2) % 4 = 3

            (1+2+3+4+5) % 4 = 3

            sum[0...4] - sum[0...1] = (3+4+5) % 4 = 0

         4. 所以在余数相同的情况下, 任意选取两个从1开始的序列和相减, 得到中间序列和必须

             整除m.  (个数: 从个数中选取2个. C几2).

 

代码:

 #include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define MAX 10005

int ca[MAX];
int n, m;
int t;
int sum;

int main()
{
// freopen("input.txt","r",stdin);
 int i, j;
 int result;
 while(scanf("%d %d",&n,&m) != EOF)
 {
  memset(ca,0,sizeof(ca));
  result = 0;
  sum = 0;
  for(i = 0; i < n; ++i)
  {
   scanf("%d",&t);
   sum = (sum + t) % m;
   if(sum == 0) result++;
   ca[sum]++;
  }

  for(i = 0; i < m; ++i)
  {
   if(ca[i] != 0)
    result += ca[i] * (ca[i] - 1) / 2;
  }
  printf("%d\n",result);
 }
 return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值