1. 程式人生 > >Codeforces 1029D(數論+思維)

Codeforces 1029D(數論+思維)

傳送門

題面:

D. 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 aa, consisting of nn positive integers.

Let's call a concatenation of numbers xx and yy the number that is obtained by writing down numbers xx and yy one right after another without changing the order. For example, a concatenation of numbers 1212 and 34563456 is a number 123456123456.

Count the number of ordered pairs of positions (i,j)(i,j) (i≠ji≠j) in array aa such that the concatenation of aiai and ajaj is divisible by kk.

Input

The first line contains two integers nn and kk (1≤n≤2⋅1051≤n≤2⋅105, 2≤k≤1092≤k≤109).

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤1091≤ai≤109).

Output

Print a single integer — the number of ordered pairs of positions (i,j)(i,j) (i≠ji≠j) in array aa such that the concatenation of aiai and ajaj is divisible by kk.

Examples

input

Copy

6 11
45 1 10 12 11 7

output

Copy

7

input

Copy

4 2
2 78 4 10

output

Copy

12

input

Copy

5 2
3 7 19 3 3

output

Copy

0

Note

In the first example pairs (1,2)(1,2), (1,3)(1,3), (2,3)(2,3), (3,1)(3,1), (3,4)(3,4), (4,2)(4,2), (4,3)(4,3) suffice. They produce numbers 451451, 45104510, 110110, 10451045, 10121012, 121121, 12101210, respectively, each of them is divisible by 1111.

In the second example all n(n−1)n(n−1) pairs suffice.

In the third example no pair is sufficient.

題意:

    給你n個數,每個數可以兩兩拼接成一個新的數。問通過這樣拼接而構成的數中能夠成為被k乘除的個數。

題目分析:

    這道題的做法相當的巧妙!(完美融入了數論的知識)(膜出題人的大腦洞)。

    首先,直接暴力做鐵定超時,因此我們需要做一些演算法優化。

    首先,對於兩個數x,y。倘若讓他們拼接成一個新的數S,我們設y的長度為len,則有:

    而因為要判斷S是否整除k,則將S%k,則有:(x*pow(10,len)%k+y%k)%k=0

    而根據取模的性質,我們可以繼續得到:

    ( x*pow( 10,len )%k+y%k )%k=k%k 

    x*pow(10,len)%k=( k-y%k )%k

    而在這個式子中,對於左式,我們可以把每一個左式都預處理出來,存進桶裡。

    之後我們只需要列舉一遍a[i],計算 ( k - y%k )%k 。如果兩個結果相等,那麼就加在res。

    最後我們還需要減去a[i]和a[i]自己配對的情況即為答案。

程式碼:

#include <bits/stdc++.h>
#define maxn 200005
using namespace std;
typedef long long ll;
int a[maxn];
map<int,ll>mp[20];
int main()
{
    int n,k;
    cin>>n>>k;
    for(int i=1;i<=n;i++){//預處理出來每一個(x*pow(10,len)%k)
        scanf("%I64d",&a[i]);
        ll x=a[i];
        for(int j=1;j<=10;j++){
            x=x*10%k;
            mp[j][x]++;
        }
    }
    ll res=0;
    for(int i=1;i<=n;i++){
        int len=log10(a[i])+1;//獲取10進位制的位數
        res+=mp[len][(k-a[i]%k)%k];//獲取答案
        ll x=1;
        for(int i=1;i<=len;i++){
            x=x*10%k;
        }
        if((a[i]*x%k+a[i]%k)%k==0) res--;//排除自己跟自己配對的情況
    }
    cout<<res<<endl;
}