积性函数指对于所有互质的整数a和b有性质f(ab)=f(a)f(b)的数论函数。
狄利克雷卷积
((f * g)(n)=sum_{d mid n} f(d) gleft(frac{n}{d}
ight))
性质1:
两个积性函数的狄利克雷卷积还是积性函数。
证明:感性理解一下,两个互质的下标乘起来,相当于两个和式乘起来,因为是互质的相当于枚举到了乘积的所有约数,因为和式里面都是积性函数所以乘起来也是积性函数。
性质2:
三大运算规律:结合律,交换律,分配律。
常见运算
除数函数: (sigma_{x}(n)=sum_{d mid n} d^{x})
约数个数函数: (d(n)=sum_{d mid n} 1) 约数和函数: (sigma(n)=sum_{d n} d)
元函数: (e(n)=[n=1]({1,0,0,0,0 ldots . . .}))
恒等函数: (I(n)=1({1,1,1,1,1 ldots ldots}))
单位函数: (varepsilon(n)=n({1,2,3,4,5 ldots ldots}))
欧拉函数: (phi(n)) 莫比乌斯函数: (mu(n))
(mu(i)=left{egin{array}{c}1, i=1 \ (-1)^{k}, i=p 1 * p 2 * ldots * p k \ 0, ext { rest }end{array} ight.)
(varepsilon=phi * I Leftrightarrow n=sum_{d mid n} phi(d))
(d=I * I Leftrightarrow d(n)=sum_{d mid n} 1)
(sigma=varepsilon * I Leftrightarrow sigma(n)=sum_{d mid n} d)
(e=I * mu Leftrightarrow[n==1]=sum_{d mid n} mu(d))
(phi=varepsilon * mu Leftrightarrow phi(n) sum_{d mid n} mu(d) * frac{n}{d})
莫比乌斯反演
若
则
证明:这里需要用到前面提到的性质: (mu * I=epsilon)
给出的条件等价于 (g=f * I)
所以 (g * mu=f * I * mu=f * epsilon=f) 即 (g * mu=f) 即 结论
杜教筛
(g(1) S(n)=sum_{i=1}^{n}(f * g)(i)-sum_{i=2}^{n} g(i) Sleft(leftlfloorfrac{n}{i}
ight
floor
ight))
求解(S(n)),可以设定(f)和(g)。
((1)mu(n))前缀和
考虑到莫比乌斯函数的性质 (mu * I=epsilon,) 自然想到取 (f=mu, g=I, f * g=epsilon)
((2)varphi) 的前缀和
考虑到 (varphi) 的性质 (varphi * I=i d,) 取 (f=varphi, g=I, f * g=i d)
(3)(sum_{i=1}^{n} varphi(i) cdot i)
令 (f=varphi cdot i d, g=i d,) 考虑迪利克雷卷积的形式得到 ((f * g)(n)=sum_{d mid n}(varphi(d) cdot d) cdotleft(frac{n}{d}
ight)=)
(n sum_{d mid n} varphi(d)=n^{2})
即 ((f * g)(i)=i^{2})
这样就可以快速求得 ((f * g)(i)) 的前缀和 (frac{n(n+1)(2 n+1)}{6})
const int N=1000009;
const int mod=1e9+7;
int pre[N];
int phi[N];
int vis[N];
int prime[N];
int _2,_6;
unordered_map<int,int>mp;
void init()
{
phi[1]=1;
int cnt=0;
for(int i=2;i<=N;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
phi[i]=i-1;
}
for(int j=1;j<=cnt&&prime[j]*i<=N;j++)
{
vis[prime[j]*i]=1;
if(i%prime[j]==0)
{
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*phi[prime[j]];
}
}
}
int getsum(int n)
{
if(n<=N)return pre[n];
if(mp.count(n))return mp[n];
int res=n*(n+1)%mod*(2*n+1)%mod*_6%mod;
for(int l=2,r;l<=n;l=r+1)
{
r=n/(n/l);
res-=(l+r)*(r-l+1)/2%mod*getsum(n/l)%mod;
}
return mp[n]=res%mod;
}
int qpow(int a,int b,int mod)
{
if(b==0)return 1;
if(b%2==0)
{
int temp=qpow(a,b/2,mod)%mod;
return temp*temp%mod;
}
else
{
return qpow(a,b-1,mod)*a%mod;
}
}
main(void)
{
init();
for(int i=1;i<=N;i++)
{
pre[i]=(pre[i-1]+i*phi[i])%mod;
}
int t=read();
_2=qpow(2,mod-2,mod);//2乘法逆元
_6=qpow(6,mod-2,mod);//6乘法逆元
while(t--)
{
int n=read();
int a=read();
int b=read();
printf("%lld
",(getsum(n)-1+mod)%mod*_2%mod);
}
}