Editorial for COUNTER
Remember to use this editorial only when stuck, and not to copy-paste code from it. Please be respectful to the problem author and editorialist.
Submitting an official solution before solving the problem yourself is a bannable offence.
Submitting an official solution before solving the problem yourself is a bannable offence.
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n,k;
const int max_digits=17;
ll exp_rem[max_digits];
ll remainder_count[max_digits][1000];
//max solution=n*n-1 llmmax=9223372036854775807<-> log10->18.9 10^9
struct number{
ll rem;
int dig_count;
void get_set(){
cin>>rem;
dig_count=naivelog10(rem);
rem%=k;
}
int naivelog10(ll x){
int count=0;
while(x){
x/=10;
count++;
}
return count;
}
};
int main(){
cin>>n>>k;
number arr[n];
ll temp=1;
//setting exp10 mods ->O(c)
for(int i=0;i<max_digits;i++){
exp_rem[i]=temp;
temp*=10;
temp=temp%k;
}
for(int i=0;i<n;i++){
//getting input and setting rem and digitcount ->O(n*max_digits)->O(n) or O(nlog(m)) where m is the maximum number
arr[i].get_set(); //sets remainder and digit_count
//increasing remainder count for every corresponding exponent of 10 ->O(n*max_digits)->O(n) or O(nlog(m))
for(int j=0;j<max_digits;j++){ //can also start with 1 since it cant be used
ll remainder=(exp_rem[j]*arr[i].rem)%k;
remainder_count[j][remainder]++;
}
}
ll res=0;
// adding the remainder counts(with self counts added) ->O(n)
//concat(other_number,this_number)
for(int i=0;i<n;i++){
int other_rem;
if(arr[i].rem==0)other_rem=0;
else other_rem=k-arr[i].rem;
res+=remainder_count[arr[i].dig_count][other_rem];
}
// subtracting self concatenations
for(int i=0;i<n;i++){
if((arr[i].rem+arr[i].rem*exp_rem[arr[i].dig_count])%k==0)res--;
}
cout<<res<<endl;
}