Code : Concatenated Multiples
#include <bits/stdc++.h>
using namespace std;
int get_len(int num) { return to_string(num).length(); }
void solve(vector<long long> &a, int k) {
int n = a.size();
vector<long long> pow10(10 + 1);
pow10[0] = 1;
for (int i = 1; i <= 10; i++) {
pow10[i] = (pow10[i - 1] * 10) % k;
}
map<int, map<int, int>> md;
for (int i = 0; i < n; i++) {
md[get_len(a[i])][a[i] % k]++;
}
long long ans = 0;
for (int i = 0; i < n; i++) {
// To avoid counting (i == j), temporarily remove this element.
md[get_len(a[i])][a[i] % k]--;
for (int len = 1; len <= 10; len++) {
int have = (pow10[len] * (a[i] % k)) % k;
int need = (-have) % k;
if (need < 0) {
need += k;
}
ans += md[len][need];
}
// Add the element back.
md[get_len(a[i])][a[i] % k]++;
}
cout << ans << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k;
cin >> n >> k;
vector<long long> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
solve(a, k);
return 0;
}
#include <bits/stdc++.h>
using namespace std;
void solve(vector<long long> &a, int k) {
int n = a.size();
vector<int> getlen(n);
vector<long long> getmod(n);
vector<long long> pow10(10 + 1);
pow10[0] = 1;
for (int i = 1; i <= 10; i++) {
pow10[i] = (pow10[i - 1] * 10) % k;
}
map<int, map<int, int>> md;
for (int i = 0; i < n; i++) {
getlen[i] = to_string(a[i]).length();
getmod[i] = a[i] % k;
md[getlen[i]][getmod[i]]++;
}
long long ans = 0;
for (int i = 0; i < n; i++) {
// To avoid counting (i == j), temporarily remove this element.
md[getlen[i]][getmod[i]]--;
for (int len = 1; len <= 10; len++) {
int have = (pow10[len] * (getmod[i])) % k;
int need = (-have) % k;
if (need < 0) {
need += k;
}
auto &mp = md[len];
if (mp.find(need) != mp.end()) {
ans += mp[need];
}
}
// Add the element back.
md[getlen[i]][getmod[i]]++;
}
cout << ans << "\n";
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int n, k;
cin >> n >> k;
vector<long long> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
solve(a, k);
return 0;
}