1. 程式人生 > >codeforces 1029D Concatenated Multiples 預處理+二分

codeforces 1029D 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 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,每兩個數連線起來mod k==0的組合有多少個.

思路:n*n的複雜度是不可能的,應為求的是(a[i]*10^{^{len(a[j])}}+a[j])mod k==0,所以當a[i]*10^{lena[j]}modk+a[j]modk==k||==0即可,所以我們先預處理出每一個數所有len[a[j]]的mod,存入對應len的的一個vector中,在列舉每一個數當這個數是a[j]時所有可能答案,如果自己和自己可以連線答案減1,複雜度為10*n*log(n),完全可以過。

反思:最開始的思路基本上就是正確的,開始的時候想到懶得去全部預處理,每到一個數了就記錄一下所有的情況,用的map記錄,然後加上前面的可能,這樣不用考慮自己和自己連,結果T的我不要不要的,怎麼都是一樣的10*n*log(n)的複雜度,想不通。

ac程式碼:

#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const ll linf=8e18+9e17;
const int mod=1e9+7;
const double e=exp(1.0);
const double pi=acos(-1);
const double eps=1e-6;
ll a[maxn]={0};
int len[maxn]={0};
vector<ll>v[11];
int main()
{
	int n;
	ll k,L[11]={1,10,100,1000,10000,
	100000,1000000,10000000,100000000,1000000000,10000000000};
	scanf("%d%lld",&n,&k);
	for(int i=1;i<=n;i++)
	{
	 scanf("%lld",&a[i]);
	 len[i]=(int)log10(a[i])+1;
	 ll base=10;
	 for(int j=1;j<=10;j++)
	{
		v[j].push_back((base%k)*(a[i]%k)%k);
		base=10*base;
	}
	}
	for(int i=1;i<=10;i++)sort(v[i].begin(),v[i].end());
	ll ans=0;
	for(int i=1;i<=n;i++)
	{
		int r=upper_bound(v[len[i]].begin(),v[len[i]].end(),(k-a[i]%k)%k)-v[len[i]].begin();
		int l=lower_bound(v[len[i]].begin(),v[len[i]].end(),(k-a[i]%k)%k)-v[len[i]].begin();
		ans+=(ll)(r-l);
		if(((a[i]%k)+L[len[i]]%k*a[i]%k)%k==0)ans--;
		//cout<<ans<<endl;
	}
	printf("%lld\n",ans);
	return 0;
}

TLE程式碼:

#include<stdio.h>
#include<string.h>
#include<cmath>
#include<stdlib.h>
#include<time.h>
#include<algorithm>
#include<iostream>
#include<vector>
#include<queue>
#include<set>
#include<map>
#define ll long long
#define qq printf("QAQ\n");
using namespace std;
const int maxn=2e5+5;
const int inf=0x3f3f3f3f;
const ll linf=8e18+9e17;
const int mod=1e9+7;
const double e=exp(1.0);
const double pi=acos(-1);
const double eps=1e-6;
ll a[maxn];
inline ll input()
{
	char c;
	ll ans=0;
	while((c=getchar())!='\n'&&c!=' ')
	{
		ans=ans*10+c-'0';
	}
	return ans;
}

#define FI(n) FastIO::read(n)
namespace FastIO {
	const int SIZE = 1 << 16;
	char buf[SIZE], obuf[SIZE], str[60];
	int bi = SIZE, bn = SIZE, opt;
	int read(char *s) {
		while (bn) {
			for (; bi < bn && buf[bi] <= ' '; bi++);
			if (bi < bn) break;
			bn = fread(buf, 1, SIZE, stdin);
			bi = 0;
		}
		int sn = 0;
		while (bn) {
			for (; bi < bn && buf[bi] > ' '; bi++) s[sn++] = buf[bi];
			if (bi < bn) break;
			bn = fread(buf, 1, SIZE, stdin);
			bi = 0;
		}
		s[sn] = 0;
		return sn;
	}
	bool read(ll& x) {
		int n = read(str), bf;
		if (!n) return 0;
		int i = 0; if (str[i] == '-') bf = -1, i++; else bf = 1;
		for (x = 0; i < n; i++) x = x * 10 + str[i] - '0';
		if (bf < 0) x = -x;
		return 1;
	}
};
using namespace FastIO;
int getbit(int x)
{
	int ans=0;
	while(x)
	{
		x/=10;
		ans++;
	}
	return ans;
}
int main()
{
	int n,num[15]={0};
	ll ans=0,cnt=0;
	ll k;
	scanf("%d%lld",&n,&k);
	getchar();
//	map<int,int>mp[15];
	//map<int,int>mp1[15];
	multiset<ll>ms1[15],ms2[15];
	//int cnt1[15][2]={0},cnt2[15][2]={0};
	for(int i=1;i<=n;i++)
	{
		//scanf("%lld",&a[i]);
		 a[i]=input();
		// read(a[i]);
		 int bit=getbit(a[i]);//(int)log10(a[i])+1;
		 ll base=10;
		 
		 cnt+=(ll)ms1[bit].count((k-a[i]%k)%k);
		 //ans+=(ll)mp[bit][(k-a[i]%k)%k];
		 for(int j=1;j<=10;j++)
		 {
		 	//mp[j][((a[i]%k)*(base%k))%k]++;//a[i]在後面
		 	ms1[j].insert(((a[i]%k)*(base%k))%k);
		 	
			//ans+=mp1[j][(k-((a[i]%k)*(base%k))%k)%k]; //a[i]在前面 
		 	
			cnt+=ms2[j].count((k-((a[i]%k)*(base%k))%k)%k);
		 	
			base=base*10;
		 }
		 //mp1[bit][a[i]%k]++;
		 ms2[bit].insert(a[i]%k);
	 }
	 
	 //printf("%lld\n",ans);
	 printf("%lld\n",cnt);
	 return 0;
}