loj124 除数函数求和 1

loj124 除数函数求和 1

https://loj.ac/problem/124

$\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 }

 

posted @ 2018-07-12 09:18  hehe_54321  阅读(514)  评论(0编辑  收藏  举报
AmazingCounters.com