トーシェント関数の和
(math/totient_sum.hpp)
Verified with
Code
#pragma once
#include<map>
/**
* @brief トーシェント関数の和
*/
template<typename T>
T totient_sum(long long n){
static std::map<long long,T> m2;
static bool init=1;
static long long* m=new long long[10000000]();
if(init){
init=0;
long long k=1e7;
for(long long i=1;i<=k;i++)m[i]=i;
for(long long i=1;i<=k;i++)for(long long j=i*2;j<=k;j+=i)m[j]-=m[i];
for(long long i=1;i<k;i++)m[i+1]+=m[i];
}
if(n<1e7)return m[n];
else if(m2.count(n))return m2[n];
T ans=T(n)*(n+1)/2;
long long mx=0;
for(long long i=1;i*i<n;i++){
ans-=T(n/i-n/(i+1))*totient_sum<T>(i);
mx=n/(i+1)+1;
}
for(long long i=2;i<mx;i++){
ans-=totient_sum<T>(n/i);
}
return m2[n]=ans;
}
#line 2 "math/totient_sum.hpp"
#include<map>
/**
* @brief トーシェント関数の和
*/
template<typename T>
T totient_sum(long long n){
static std::map<long long,T> m2;
static bool init=1;
static long long* m=new long long[10000000]();
if(init){
init=0;
long long k=1e7;
for(long long i=1;i<=k;i++)m[i]=i;
for(long long i=1;i<=k;i++)for(long long j=i*2;j<=k;j+=i)m[j]-=m[i];
for(long long i=1;i<k;i++)m[i+1]+=m[i];
}
if(n<1e7)return m[n];
else if(m2.count(n))return m2[n];
T ans=T(n)*(n+1)/2;
long long mx=0;
for(long long i=1;i*i<n;i++){
ans-=T(n/i-n/(i+1))*totient_sum<T>(i);
mx=n/(i+1)+1;
}
for(long long i=2;i<mx;i++){
ans-=totient_sum<T>(n/i);
}
return m2[n]=ans;
}
Back to top page