Concatenated Multiples
time limit per test 2 seconds
memory limit per test 256 megabytes
input standard input
output standard output
You are given an array a, consisting of n positive integers.
Let's call a concatenation of numbers x and y the number that is obtained by writing down numbers x and y one right after another without changing the order. For example, a concatenation of numbers 12 and 3456 is a number 123456.
Count the number of ordered pairs of positions (i,j) (i≠j) in array a such that the concatenation of ai and aj is divisible by k.
Input
The first line contains two integers n and k (1≤n≤2⋅105, 2≤k≤109).
The second line contains n integers a1,a2,…,an (1≤ai≤109).
Output
Print a single integer — the number of ordered pairs of positions (i,j) (i≠j) in array a such that the concatenation of ai and aj is divisible by k.
Examples
Input
6 11
45 1 10 12 11 7
Output
7
Input
4 2
2 78 4 10
Output
12
Input
5 2
3 7 19 3 3
Output
0
Note
In the first example pairs (1,2), (1,3), (2,3), (3,1), (3,4), (4,2), (4,3) suffice. They produce numbers 451, 4510, 110, 1045, 1012, 121, 1210, respectively, each of them is divisible by 11.
In the second example all n(n−1) pairs suffice.
In the third example no pair is sufficient.
题目大意:
给定一系列的数,挑出两个数连起来后可以被题目中给定的 k 整除,这样的数可以有多少对?比如 2 “+” 7 “=” 27 可以被3 整除。
思路:
直接暴力枚举的话,复杂度O(n^2)是一定不可以的,所以我们考虑一些预处理来求解的降低复杂度。对于两个数a、b,若要找有多少 b 使得 (a + b) % k = 0,则问题等价于找有多少个 k - a % k。
回到这个问题,我们预处理每个数计算出它 mod k 的值 p,并算出它的长度 len,通过 m[len][p] 来计数。之后,对每个数 a[i] 枚举 t = a[i] * 1ej % k (j=1,...,11),则 m[j][(k - t) % k] 就是 a[i] 右接一个长度为 j 的数所有正确的答案数。将整个数组过一遍,对所有正确的答案数求和就是最终的答案。复杂度接近 O(nlogn)。
代码:
#include<map>
#include<cmath>
#include<cstdio>
#define ll long long
using namespace std;
const int maxn = 2e5 +5;
map<ll,ll> m[20];
ll a[maxn];
int main()
{
ll n,k;
ll ans = 0;
scanf("%I64d %I64d",&n,&k);
for(int i = 0;i < n; ++i)
{
scanf("%I64d",&a[i]);
ll p = a[i] % k;
ll len = log10(a[i]) + 1;
ll tp = a[i];
m[len][p]++;
}
for(int i = 0;i < n; ++i)
{
ll p = a[i] * 10 % k;
ll len = log10(a[i]) + 1;
for(int j = 1;j < 11; ++j)
{
if(j == len && (k - p) % k == a[i] % k) --ans;// Delete itself
ans += m[j][(k - p) % k];
p = p * 10 % k;
}
}
printf("%I64d\n",ans);
return 0;
}