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.
#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;


}