BZOJ1257
![ans=\sum _{i=1}^nk-[k/i]*i BZOJ1257, 2226, 2705[欧拉函数] [整除分块]_i++](https://file.cfanz.cn/uploads/gif/2022/07/12/8/T1cEcN3bOG.gif)
模转除, 整除分块就可以了
#include<bits/stdc++.h>
#define LL long long
using namespace std;
int n,k; LL ans;
int main(){
scanf("%d%d",&n,&k);
ans = (LL)k * (LL)n;
LL ret = 0;
for(int l=1,r;l<=n;l=r+1){
if(k/l==0) break;
r = k/(k/l); if(r>n) r = n;
ret += (LL)(k/l) * (LL)(l+r) * (LL)(r-l+1) / 2 ;
} printf("%lld", ans - ret);
return 0;
}BZOJ 2226
![Ans=\sum _{i=1}^nlcm(i,n)=n\sum _{i=1}^ni*gcd(i,n) BZOJ1257, 2226, 2705[欧拉函数] [整除分块]_#include_02](https://file.cfanz.cn/uploads/gif/2022/07/12/8/C81Gf1Fd3Q.gif)
枚举一下gcd
![=n\sum _{k|n}^n\sum _{i=1}^ni/k*[gcd(i,n)=k]=n\sum_{k|n}^n\sum _{i=1}^{n/k}i*[gcd(i,n/k)=1]=n\sum_{k|n}\varphi(n/k)*(n/k)/2 BZOJ1257, 2226, 2705[欧拉函数] [整除分块]_#define_03](https://file.cfanz.cn/uploads/gif/2022/07/12/8/aT6GYeT6a2.gif)
然后线性筛+调和级数预处理一下就可以了
#include<bits/stdc++.h>
#define N 1000050
#define LL long long
using namespace std;
int prim[N],isp[N],tot,phi[N];
LL val[N],ans[N];
void prework(){
phi[1] = 1;
for(int i=2;i<=N-50;i++){
if(!isp[i]) prim[++tot] = i, phi[i] = i-1;
for(int j=1;j<=tot;j++){
if(i*prim[j] > N-50) break;
isp[i * prim[j]] = 1;
if(i%prim[j]==0){ phi[i*prim[j]] = phi[i] * prim[j]; break;}
else phi[i*prim[j]] = phi[i] * (prim[j] - 1);
}
}
val[1] = 1;
for(int i=2;i<=N-50;i++) val[i] = (LL)phi[i] * (LL)i / 2ll;
for(int i=1;i<=N-50;i++)
for(int j=i;j<=N-50;j+=i) ans[j] += val[i];
}
int main(){
prework(); int T; scanf("%d",&T);
while(T--){ int n; scanf("%d",&n); printf("%lld\n",(LL)n*ans[n]);}
return 0;
}BZOJ2705
![Ans = \sum _{k|n}k*\varphi(n/k) BZOJ1257, 2226, 2705[欧拉函数] [整除分块]_i++_04](https://file.cfanz.cn/uploads/gif/2022/07/12/8/15fcYf03cK.gif)
#include<bits/stdc++.h>
#define LL long long
using namespace std;
LL ans,n;
int phi(int x){
int ans = x;
for(int i=2;i*i<=x;i++){
if(x % i == 0){
ans = ans / i * (i-1);
while(x % i == 0) x /= i;
}
}
if(x > 1) ans = ans / x * (x-1);
return ans;
}
int main(){
scanf("%lld",&n);
for(int i=1; i*i <= n; i++){
if(n%i == 0){
ans += (LL)i * (LL)phi(n/i);
if(i*i != n) ans += (LL)(n/i) * (LL)phi(i);
}
} printf("%lld",ans); return 0;
}










