# 51nod 1575 Gcd and Lcm

51nod 专栏收录该内容
3 篇文章 0 订阅

T $T$ 组数据，每组数据给出一个正整数 n$n$ ，求 ni=1ij=1ik=1lcm(gcd(i,j),gcd(i,k))mod232 $\sum_{i=1}^{n}{\sum_{j=1}^{i}{\sum_{k=1}^{i}{\text{lcm}(\gcd(i,j),\gcd(i,k))}}} \bmod 2^{32}$
T10,n109 $T \leq 10, n \leq 10^9$

i=1nj=1ik=1ilcm(gcd(i,j),gcd(i,k))=i=1nj=1ik=1id1d2[gcd(i,j)=d1][gcd(i,k)=d2]lcm(d1,d2)=i=1nd1|id2|ilcm(d1,d2)j=1i[gcd(i,j)=d1]k=1i[gcd(i,k)=d2]=i=1nd1|id2|ilcm(d1,d2)φ(id1)φ(id2)

i=1nd1|id2|ilcm(d1,d2)φ(id1)φ(id2)=i=1nd1|id2|id|d1,d|d2d|d1d,d|d2dμ(d)d2d1ddd2dddφ(id1dddd)φ(id2dddd)=i=1nd|id|iddμ(d)d2d1dd|iddd1ddφ(iddd1dd)d2dd|iddd2ddφ(iddd2dd)=i=1nd|id|iddμ(d)d2(d′′dd|iddd′′ddφ(iddd′′dd))2

i=1nd|id|iddμ(d)d2(d′′dd|iddd′′ddφ(iddd′′dd))2=i=1nxyz=ixμ(y)y2(d|zdφ(zd))2=i=1n(idid2μ(idφ)2)(i)

f(pk)=pi|pkg2(pi)h(pki)=g2(pk)+i=0k1((i+1)piipi1)2)pki(1p)=g2(pk)+pki=0k1(i+1)2pi+1+(i+1)(3i+1)pii(3i+2)pi1+i2pi2=g2(pk)+pk(i=0ki2pi+i=0k1(i+1)(3i+1)pii=0k2((i+1)(3i+5)pi)+i=0k3(i+2)2pi)

f(pk)[pk1]=1f(pk)[p2k2]=k2(k2)2+(k1)(3k5)(k1)(3k1)=0f(pk)[p2k1]=2k(k+1)(k1)2+k(3k2)=2k1f(pk)[p2k]=(k+1)2k2=2k+1

f(pk)=(2k+1)(p2kp2k1)+pk1=pk1((2k+1)φ(pk+1)+1) $f(p^k)=(2k+1)(p^{2k}-p^{2k-1})+p^{k-1}=p^{k-1}((2k+1)\varphi(p^{k+1})+1)$ ，但是这样做非常麻烦，不妨回到原式来做如下推导
f(pk)=i=1pkj=1pklcm(gcd(i,pk),gcd(j,pk))=i=0kj=0kpmax(i,j)φ(pki)φ(pkj)=i=0kpiφ(pki)(2j=0i1φ(pkj)+φ(pki))=pk(2pk1)+i=0k1φ(pk)(2pk(pki+pki1))=(2k+2)p2k2kp2k1pki=0k1(p2kip2ki2)=(2k+1)(p2kp2k1)+pk1

#include <cmath>
#include <stdio.h>
#include <algorithm>
const int maxn = 31623, delta = 100000, maxd = 10001, maxl = delta + 1;
int tot, pr[maxn], d[maxn], tf[maxd];
int solve(int L, int R) // [L, R]
{
if(L > R)
return 0;
static int _val[maxl], _rem[maxl];
int *val = _val - L, *rem = _rem - L, lim = (int)ceil(sqrt(R));
for(int i = L; i <= R; ++i)
{
val[i] = 1;
rem[i] = i;
}
for(int i = 0; i < tot && pr[i] <= lim; ++i)
for(int j = R / pr[i] * pr[i]; j >= L; j -= pr[i])
{
rem[j] /= pr[i];
int cnt = 1, pk = pr[i];
for( ; rem[j] >= maxn && rem[j] % pr[i] == 0; rem[j] /= pr[i], ++cnt, pk *= pr[i], val[j] *= pr[i]);
if(rem[j] < maxn)
for( ; d[rem[j]] == pr[i]; rem[j] /= pr[i], ++cnt, pk *= pr[i], val[j] *= pr[i]);
val[j] *= (cnt << 1 | 1) * (pr[i] - 1) * pk + 1;
}
int ret = 0;
for(int i = L; i <= R; ++i)
{
if(rem[i] > 1)
val[i] *= 3 * (rem[i] - 1) * rem[i] + 1;
ret += val[i];
}
return ret;
}
inline int solve(int n) // [1, n]
{
int idx = n / delta, low = idx * delta, upp = low + delta;
return n - low <= upp - n ? tf[idx] + solve(low + 1, n) : tf[idx + 1] - solve(n + 1, upp);
}
int main()
{
for(int i = 2; i < maxn; ++i)
{
if(!d[i])
pr[tot++] = d[i] = i;
for(int j = 0, k; (k = i * pr[j]) < maxn; ++j)
{
d[k] = pr[j];
if(d[i] == pr[j])
break;
}
}
// parse table data from string to array, satisfied that tf[i] = solve(1, i * delta).
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
printf("%u\n", solve(n));
}
return 0;
}
• 1
点赞
• 5
评论
• 0
收藏
• 一键三连
• 扫一扫，分享海报

12-05 422

09-02 726
10-24 382
01-14 72
08-02 73
01-14 59
12-28 286
10-21 280