给定长度为 NN 的数组 ,求
∑1≤i≤n,1≤j≤ma[gcd(i,j)]∑1≤i≤n,1≤j≤ma[gcd(i,j)]
数据范围: 1≤n,m≤N≤1051≤n,m≤N≤105 。
设
f(n,m)=∑i=1n∑j=1ma[gcd(i,j)]=∑d=1min(n,m)∑i=1n∑j=1ma[d]×[gcd(i,j)==d]=∑d=1min(n,m)a[d]×∑i=1nd∑j=1md[gcd(i,j)==1]f(n,m)=∑i=1n∑j=1ma[gcd(i,j)]=∑d=1min(n,m)∑i=1n∑j=1ma[d]×[gcd(i,j)==d]=∑d=1min(n,m)a[d]×∑i=1nd∑j=1md[gcd(i,j)==1]
先知道莫比乌斯函数的定义:
∑d|nμ(d)=1 (当n=1)∑d|nμ(d)=0 (当n>1)∑d|nμ(d)=1 (当n=1)∑d|nμ(d)=0 (当n>1)
设
g(n,m)=∑i=1n∑j=1m[gcd(i,j)==1]=∑i=1n∑j=1m∑d|gcd(i,j)μ(d)=∑d=1min(n,m)μ(d)×nd×mdg(n,m)=∑i=1n∑j=1m[gcd(i,j)==1]=∑i=1n∑j=1m∑d|gcd(i,j)μ(d)=∑d=1min(n,m)μ(d)×nd×md
则
f(n,m)=∑d=1min(n,m)a[d]×g(nd,md)f(n,m)=∑d=1min(n,m)a[d]×g(nd,md)
复杂度计算:∑ni=1ni≈O(nlogn)∑i=1nni≈O(nlogn)
美团的笔试题给定了A数组,即a1=p,ai=(ai+153)%pa1=p,ai=(ai+153)%p 。
代码如下:
#include <bits/stdc++.h>
using namespace std;
int a[100007],mu[100007];
using ll = long long;
ll g(int n, int m)
{
ll ret = 0;
for(int i=1; i<=min(n, m); ++i)
ret+=(ll)mu[i]*(n/i)*(m/i);
return ret;
}
int main()
{
int N,n,m,p;
scanf("%d%d%d%d",&N,&n,&m,&p);
ll ans = 0;
mu[1]=1;
for(int i=1; i<=N; ++i)
for(int j=2*i;j<=N;j+=i)
mu[j]-=mu[i];
a[1]=p;
for(int i=2; i<=N; ++i)
a[i]=(a[i-1]+153)%p;
for(int i=1; i<=min(n, m); ++i)
{
ans+=(ll)a[i]*g(n/i,m/i);
}
cout << ans << '\n';
return 0;
}