【分析】
(oldsymbol {sigma^*}) 的积性容易验证,则仅考虑其在质数幂处的值
(displaystyle oldsymbol {sigma^*}(p^k)=sum_{i=0}^kp^i[gcd(p^i, p^{k-i})=1]=sum_{i=0}^k p^i[min(i, k-i)=0]=p^k+[k>0])
由于该积性函数具有很好的性质:(oldsymbol {sigma^*}(p)=p+1=oldsymbol {sigma}(p)) ,故考虑 Powerful Number 筛:
令积性函数 (oldsymbol h) 满足 (oldsymbol {sigma^*}=oldsymbol sigma*oldsymbol h)
(egin{aligned} oldsymbol {sigma^*}(p^k)&=sum_{i=0}^koldsymbol sigma(p^i)oldsymbol h(p^{k-i})&(k>0) \\ oldsymbol {sigma^*}(p^k)&=sum_{i=1}^{k-1}oldsymbol sigma(p^i)oldsymbol h(p^{k-i})+oldsymbol sigma(p^k)+oldsymbol h(p^k) \\ oldsymbol h(p^k)&=oldsymbol {sigma^*}(p^k)-oldsymbol sigma(p^k)-sum_{i=1}^{k-1}oldsymbol sigma(p^i)oldsymbol h(p^{k-i}) end{aligned})
代入迭代得:
(egin{aligned} oldsymbol h(1)&=1 \\ oldsymbol h(p)&=oldsymbol {sigma^*}(p)-oldsymbol sigma(p)-sum_{i=1}^{1-1}oldsymbol sigma(p^i)oldsymbol h(p^{1-i})&=0 \\ oldsymbol h(p^2)&=oldsymbol {sigma^*}(p^2)-oldsymbol sigma(p^2)-sum_{i=1}^{2-1}oldsymbol sigma(p^i)oldsymbol h(p^{2-i})&=-p \\ oldsymbol h(p^3)&=oldsymbol {sigma^*}(p^3)-oldsymbol sigma(p^3)-sum_{i=1}^{3-1}oldsymbol sigma(p^i)oldsymbol h(p^{3-i})&=0 end{aligned})
继续迭代观察可发现 (oldsymbol h(p^k)=0, kgeq 3) ,可用数学归纳法证明
由此 (oldsymbol h(p^k)=egin{cases} egin{aligned} -p&, k=2 \\0&, k eq 2 end{aligned} end{cases}, k>0)
且由 Powerful Number 筛,有:
(egin{aligned} S(n)&=sum_{i=1}^noldsymbol {sigma^*}(i) \\&=sum_{i=1}^nsum_{dmid i}oldsymbol h(d)oldsymbol sigma({iover d}) \\&=sum_{d=1}^n oldsymbol h(d)sum_{i=1}^n[dmid i]oldsymbol sigma({iover d}) \\&=sum_{d in PN} oldsymbol h(d)sum_{i=1}^{n/d} oldsymbol sigma(i) \\&=sum_{d in PN} oldsymbol h(d)S_d(n/d) end{aligned})
而 (displaystyle S_d(n)=sum_{i=1}^noldsymbol sigma(i)=sum_{i=1}^n sum_{dmid i}d=sum_{d=1}^n dcdot (n/d))
对右边整除分块即可 (O(sqrt n)) 时间内求解 (S_d(n))
总复杂度计算时,考虑到 (forall din PN o exist a, bin Z^+wedge d=a^2b^3)
故 (displaystyle T(n)=sum_{a=1}^{sqrt n}sum_{b=1}^{sqrt[3]{n/a}}sqrt{nover a^2b^3}=int_1^sqrt n ext daint_1^{sqrt[3]{nover a}} ext dbcdot sqrt{nover a^2b^3}=O(sqrt nlog n))
【代码】
还不知道能不能过
#include<bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;
typedef double db;
#define fi first
#define se second
const int Lim=1e7, MAXN=Lim+10;
int fck[MAXN], prime[MAXN/10], cntprime, lst[MAXN];
ull sigma[MAXN];
inline void init() {
sigma[1]=1;
for(int i=2; i<=Lim; ++i) {
if(!fck[i]) {
fck[i]=prime[++cntprime]=i;
lst[i]=1;
sigma[i]=i+1;
}
for(int j=1; j<=cntprime; ++j)
if( prime[j]*i>Lim ) break;
else if(i%prime[j]) {
fck[ prime[j]*i ]=prime[j];
lst[ prime[j]*i ]=i;
sigma[ prime[j]*i ]=sigma[i]*sigma[ prime[j] ];
}
else {
fck[ prime[j]*i ]=fck[i]*prime[j];
lst[ prime[j]*i ]=lst[i];
if( fck[i]==i ) sigma[ prime[j]*i ]=sigma[i]*prime[j]+1;
else sigma[ prime[j]*i ]=sigma[lst[i]]*sigma[fck[i]*prime[j]];
break;
}
}
for(int i=2; i<=Lim; ++i) sigma[i]+=sigma[i-1];
}
inline ull sum1(ull n) { return (n&1)?((n+1)/2*n):(n/2*(n+1)); }
inline ull sumit(ull m) {
ull res=sigma[min(m, 10000000ull)];
for(ull l=10000000, r, d; l<=m; l=r+1) {
r=m/(d=m/l);
res+=d*(sum1(r)-sum1(l-1));
}
return res;
}
ull dfs(ull n, int flr, ull hn) {
ull m, res=hn*sumit(n);
for(int i=flr+1; i<=cntprime; ++i) {
m=n/prime[i]/prime[i];
if(!m) break;
res+=dfs(m, i, hn*(-prime[i]));
}
return res;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
init();
int T; cin>>T;
ull n;
while(T--&&cin>>n) cout<<dfs(n, 0, 1)<<"
";
cout.flush();
return 0;
}