ACM: 数论题 toj 1721

来源:互联网 发布:麻瓜编程 爬虫 编辑:程序博客网 时间:2024/05/16 13:03

                 Partial Sums

描述

 

Given a series of nnumbers a1, a2, ..., an, the partial sum of the numbers is definedas the sum of ai, ai+1, ..., aj.

You are supposed to calculate how many partial sums of a givenseries of numbers could be divided evenly by a given numberm.

输入

 

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 - thenumber 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
原创粉丝点击