您的位置:首页 > 其它

ACM: 数论题 toj 1721

2016-05-19 23:19 429 查看


                 
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. 例如:
                     
5  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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: