1029D. Concatenated Multiples(思维+数学)

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.

题意:

已知n个数和一个mod,可以将任意两个数连接起来,问连接起来的数对mod取模等于0的数字有几个

所谓连接就是数字字符串的拼接,如123和789连接结果是123789

思路:

n的范围是2e5,直接暴力,毫无疑问会超时。我们能不能换个思路呢?

conc(ai,aj)=ai*10^lenj+aj,拼接后的数字为: 前边的数字*pow(10,后边字符串的长度)+后边数字的大小

拼接后的数字能够被mod取模后为0,即(((ai*10^lenj)%mod)+aj%mod)%mod=0;

aj 的长度最长为10,我们可以预处理x=ai*10^k%mod, 1<=k<=10,dp[k][x]表示aj长度为k时,满足ai%mod=x,ai的个数

在接下来的运算中直接处理,要注意ai与aj相同的情况。

#include<cstdio>
#include<cstring>
#include<map>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N = 2e5+1;
map<LL,LL>mp[11];
int arr[N];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		scanf("%d",&arr[i]);
		LL x=arr[i];
		for(int j=1;j<=10;j++){
			x*=10;
			x%=m;
			mp[j][x]++;
		}
	}
	LL ans=0;
	for(int i=0;i<n;i++){
		int t=arr[i]%m;
		int len=log10(arr[i])+1;
		ans+=mp[len][(m-t)%m];
		LL x=1;
		for(int j=1;j<=len;j++) x=(x*10)%m;
		if(((arr[i]*x)%m+arr[i]%m)%m==0) ans--;
	}
	printf("%I64d\n",ans);
	return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值