loj124 除数函数求和 1
loj124 除数函数求和 1
$\sum_{i=1}^n(\sum_{d|i}d^k)=\sum_{i=1}^n(i^k*{\lfloor}{\frac{n}{i}}{\rfloor})$
不能直接数论分块了,但是一看数据范围,可以线性筛啊
怎么筛呢?可以把所有的$i^k$筛出来。就是质数直接算,其他的根据$(a*b)^k=a^k*b^k$在被筛掉的时候递推出来。
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define fi first 7 #define se second 8 #define mp make_pair 9 #define pb push_back 10 typedef long long ll; 11 typedef unsigned long long ull; 12 typedef pair<int,int> pii; 13 #define N 10000010 14 #define md 1000000007 15 bool nprime[N+100];int prime[N+100],len; 16 ll A[N+100],ans,n,k; 17 ll poww(ll a,ll b) 18 { 19 ll base=a,ans=1; 20 while(b) 21 { 22 if(b&1) ans=ans*base%md; 23 base=base*base%md; 24 b>>=1; 25 } 26 return ans; 27 } 28 int main() 29 { 30 ll i,j; 31 scanf("%lld%lld",&n,&k); 32 A[1]=1; 33 for(i=2;i<=n;i++) 34 { 35 if(!nprime[i]) prime[++len]=i,A[i]=poww(i,k); 36 for(j=1;j<=len&&i*prime[j]<=n;j++) 37 { 38 nprime[i*prime[j]]=1; 39 A[i*prime[j]]=A[i]*A[prime[j]]%md; 40 if(i%prime[j]==0) break; 41 } 42 } 43 for(i=1;i<=n;i++) ans=(ans+A[i]*(n/i)%md)%md; 44 printf("%lld",ans); 45 return 0; 46 }