求取余不为零的数的对数,就是总数减去取余为零的对数,取余为零必成倍数关系,若成倍数关系,枚举倍数即可,倍数变化是很快的,前10000个数平均要求1000次,10000~100000每个数只需平均求五次即可,加上判重操作,不会超时。
注意输出结果为longlong
附代码:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[100010];
int b[100010];
int main()
{
int n;
while (scanf("%d",&n)!=EOF)
{
for (int i=1;i<=100000;i++)
a[i]=b[i]=0;
int max=0;
int m=0;
for (int i=1;i<=n;i++)
{
int b1;
scanf("%d",&b1);
if (a[b1]==0)
{
m++;
b[m]=b1;
}
a[b1]++;
if (b1>max)
max=b1;
}
sort(b+1,b+m+1);
long long int ans=0;
int s=0;
long long int sum=0;
for (int i=1;i<=m;i++)
{
int cur=b[i];
ans=ans+s*a[cur];
s=s+a[cur];
for (int t=cur*2;t<=max;t+=cur)
{
sum=sum+a[t]*a[cur];
}
}
ans=ans-sum;
printf("%lld\n",ans);
}
}