Divisible Sum Pairs
Problem:
You are given an array of integers, , and a positive integer, . Find and print the number of pairs where and is evenly divisible by .
Input Format
The first line contains space-separated integers, and , respectively. The second line contains space-separated integers describing the respective values of .
Constraints
Output Format
Print the number of pairs where and is evenly divisible by .
Sample Input
6 3
1 3 2 6 1 2
Sample Output
5
Explanation
Here are the valid pairs:
Thoughts:
The naive solution is simple:
#!/bin/python
import sys
n,k = raw_input().strip().split(' ')
n,k = [int(n),int(k)]
a = map(int,raw_input().strip().split(' '))
ans = 0
for i in xrange(n):
for j in xrange(i+1, n):
if (a[i]+a[j])%k == 0:
ans += 1
print ans
This solution has time complexity of . Can we do better? Yes!
Suppose we have a pair meets the constrains. We can tell that the sum of reminders of and equals , say . With this property, we can count the reminder of each number in the input array first. And then, we can scan the counter array to compute the final number of pairs.
The time complexity of this solution is .
Solution:
#!/bin/python
import sys
n,k = raw_input().strip().split(' ')
n,k = [int(n),int(k)]
a = map(int,raw_input().strip().split(' '))
# mod_cnt is the counter array, the maximum possible length of this array is k
mod_cnt = [0]*k
# count the number of each reminder
for num in a:
mod_cnt[num%k] += 1
# mod_cnt[0] contains the numbers that have 0 as its reminder when module k
# In this set, numbers can composite pairs themselves.
# For example, suppose the indies of these numbers are [1, 3, 5, 7]. How many number of pairs are there?
# the answer is 4*3/2 = 6.
ans = mod_cnt[0]*(mod_cnt[0]-1)/2
# Then for reminders from 1 to k-1, we compute the number of pairs they can composite.
for i in xrange(1, (k+1)/2):
ans += mod_cnt[i]*mod_cnt[k-i]
# At last, if k is an even number, for example 10,
# the above loop will miss the reminder in the middle, which is 5
# we need to compute the number of pairs which in this set, similar to reminder 0
if k % 2 == 0:
ans += mod_cnt[k/2]*(mod_cnt[k/2]-1)/2
print ans