题意
定义 (amathrm i+b) 是 (n) 的约数当且仅当存在 (cmathrm i +d) 使得 ((amathrm i +b)(cmathrm i +d)=n(a,b,c,din mathbf{N}))。
设 (h(n)) 为 (n) 的约数的实部之和,要求实部大于 (0)。求 (H(n)=sum_i^n h(i))。(nleq 10^{10})。
题解
先考虑虚部大于 (0) 的情况。设 (n=(amathrm i +b)(cmathrm i d)(a>0)),则 (ac-bd=n,ad+bc=0)。设:
[egin{aligned}
a=px\
p=qx\
c=py\
d=-qy\
pot q
end{aligned}
]
则 ((p,q,x,y)) 唯一确定 ((a,b,c,d))。
记:
-
[g(n)=sum_{p^2+q^2=n} [pot q]p ]
-
[f(n)=sum_{p^2+q^2=n}p ]
-
[S(n)=sum_{i=1}^{n}sigma_1(i) ]
问题化为:
[egin{aligned}
&sum_{p,q,x,y}[pot q][xy(p^2+q^2)leq n]px\
=&sum_{i=1}^{n} left(sum_{p^2+q^2=i}[pot q]p
ight)+left(sum_{xyleq n /i}x
ight)\
=&sum_{i=1}^{n}g(i)S(lfloor dfrac{x}{i}
floor)
end{aligned}
]
(S(n)) 在小数据处线性筛预处理,大数据处整除分块。
[egin{aligned}
sum_{i=1}^n g(i)=&sum_{p^2+q^2leq n}[pot q]p\
&sum_{i=1}^{sqrt n}imu(i)sum_{j=1}^{lfloor frac{n}{i^2}
floor}f(j)
end{aligned}
]
(g) 的前缀和暴力计算,(f) 的前缀和可以暴力枚举 (p)。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int M1=1.2e5,M2=5e6,mod=1004535809,inv2=(mod+1)/2;
bool boo[M2];
int sig[M2],mu[M2],pri[M2],r[M2],cnt;
struct IZHR2MJy{
int lim=0;
void init(int n){
sig[1]=1;
mu[1]=1;
lim=n;
for(int i=2;i<=n;i++){
if(!boo[i]){
r[i]=1;
sig[i]=i+1;
pri[cnt++]=i;
mu[i]=-1;
}
for(int j=0;j<cnt&&i*pri[j]<=n;j++){
int v=i*pri[j];
boo[v]=1;
if(i%pri[j]){
sig[v]=sig[i]*1ll*sig[pri[j]]%mod;
mu[v]=-mu[i];
r[v]=i;
}else{
sig[v]=(sig[i]*1ll*pri[j]+sig[r[i]])%mod;
r[v]=r[i];
break;
}
}
}
for(int i=1;i<=n;i++)sig[i]=(sig[i-1]+sig[i])%mod;
}
int _(ll x){
x%=mod;
return x*(x+1)/2%mod;
}
int operator()(ll x){
if(x<=lim)return sig[x];
int ans=0;
for(ll l=1,r;l<=x;l=r+1){
r=x/(x/l);
int t=x/l%mod;
ans=(ans+(_(r)-_(l-1)+mod)*1ll*t)%mod;
}
return ans;
}
}S;
int F(ll n){
int ans=0;
for(ll i=1;i*i<=n;i++)
ans=(ans+i*int(sqrt(n-i*i)))%mod;
return ans;
}
int G(ll n){
int lsti=-1,lstf=0,ans=0;
for(ll i=1;i*i<=n;i++){
if(n/i/i!=lsti){
lsti=n/i/i;
lstf=F(n/i/i);
}
ans=(ans+mu[i]*i*lstf)%mod;
}
return ans;
}
int main(){
ll n;
scanf("%lld",&n);
S.init(pow(n,0.667));
int ans=0;
for(ll l=1,r,sl=0;l<=n;l=r+1){
r=n/(n/l);
int sr=G(r);
ans=(ans+(sr-sl)*1ll*S(n/l))%mod;
sl=sr;
}
cout<<((ans+mod)*2ll+S(n))%mod<<endl;
}