分类讨论考虑a[i]放在高位还是低位,用cnt和cnt2数组记录余数为i数位为j的个数,每次加起来就行了,不过记得要除以2,因为先枚举高位后枚举低位的对称的
#include<iostream>
#include<cstring>
using namespace std;
typedef long long ll;
ll cnt[100010][11];
ll cnt2[100010][11];
int n,k;
int a[100010];
ll res;
int get(int x)
{
int res=0;
while(x)
{
x/=10;
res++;
}
return res;
}
ll my_pow(int x)
{
ll res=1;
while(x--)
{
res*=10;
}
return res;
}
int main()
{
cin >> n >> k;
for(int i = 0;i < n ; i++)
{
cin>>a[i];
int len=get(a[i]);
cnt2[a[i]%k][len]++;
for(int j=1;j<=10;j++)
cnt[(ll)a[i]%k*my_pow(j)%k][j]++;
}
ll res=0;
for(int i=0;i<n;i++)
{
int t = a[i]%k;
int m = (k - t)%k;
int len = get(a[i]);
cnt2[a[i]%k][len]--;
for(int j=1;j<=10;j++)
cnt[(ll)a[i]%k*my_pow(j)%k][j]--;
//a[i]放在高位
int M;
for(int j=1;j<=10;j++)
{
M = (k-a[i]%k*my_pow(j)%k)%k;
if(cnt2[M][j]>0)
res += cnt2[M][j];
}
//放在低位
if(cnt[m][len]>0)
res += cnt[m][len];
cnt2[a[i]%k][len]++;
for(int j=1;j<=10;j++)
cnt[(ll)a[i]%k*my_pow(j)%k][j]++;
}
cout << res/2 << endl;
return 0;
}
你这个头像差点笑喷我
%%%%%
%%%%%
%巨