Codeforces #506 D. Concatenated Multiples

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 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⋅10^5, 2≤k≤10^9).

The second line contains n integers a1,a2,…,an (1≤ai≤10^9).

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.

概述

    给定数字集,你可以把其中任两个数按数位拼接,要求拼接后的数能被k整除,问共有多少种拼接方式。

思路

    这道题并没有可数学简化的地方,只有遍历计算一条路。

    假设a拼接到bn位数b的左边,得到的数是a*10^bn+b,若 a*10^bn+b mod k == 0 则计数+1.

    然而暴力遍历是O(n^2),难点就是如何将时间复杂度降到O(nlogn)。

    遍历a时,从 a*10^bn+b mod k == 0 可以看到如果固定bn,b的取值就被固定。如果把b按bn分类搜索,就只要对每个bn查找固定值b。

    提到查找固定值个数,容易想到哈希表和有序结构两种方式,但k过大,不考虑哈希表。

    multiset插入和查找时间复杂度是O(logn)。使用multiset优化后插入加遍历复杂度最坏不超过O(n*(logn+9log(n/9))),但可能常数过大,会TLE。换用vector排序就能过。

  • 0<bn<11,对10^bn的结果预计算可节约时间

代码

#include<bits\stdc++.h> 
typedef long long ll;
using namespace std; 
const int MAX=2e5+5;

int a[MAX];        //input
int len[MAX];      //len of ai
int mt[11];        //(10^i)%k
vector<int> d[11]; //a's of len i

int main(){
	int n,k;
	cin>>n>>k;
	int t=10%k;
	for(int i=1;i<11;i++){
		mt[i]=t;
		t=(10*t)%k;
	}
	for(int i=0;i<n;i++){
		int t,c=0;
		cin>>t;
		a[i]=t%k;
		while(t){
			c++;
			t/=10;
		}
		len[i]=c;
		d[c].push_back(a[i]);
	}
	ll cnt=0;
	for(int i=1;i<11;i++)
		sort(d[i].begin(),d[i].end());
	for(int i=0;i<n;i++){
		for(int j=1;j<11;j++){
			int t=k-((ll)a[i]*mt[j])%k;
			if(t==k) t=0;
			cnt+=(upper_bound(d[j].begin(),d[j].end(),t)-lower_bound(d[j].begin(),d[j].end(),t));
			if(len[i]==j && a[i]==t) cnt--;
		}
	}
	cout<<cnt;
	return 0;
}

http://www.cnblogs.com/hizcard/  转载请注明出处 

猜你喜欢

转载自blog.csdn.net/hizcard/article/details/82113707