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的复杂度是不可能的,应为求的是,所以当即可,所以我们先预处理出每一个数所有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;
}