解决思路:幂函数是完全积性函数,用欧拉筛计算
1
\small1
1到
n
\small n
n的幂函数的值存入数组
p
o
w
F
u
n
\small powFun
powFun。 观察题目,发现
p
o
w
F
u
n
[
i
]
\small powFun[i]
powFun[i]会被重复计算,被计算的个数正好是
1
\small1
1到
n
\small n
n中
i
\small i
i的倍数的个数,所以
a
n
s
\small ans
ans每次加一下对答案的贡献就好
(
\small(
(
p
o
w
F
u
n
[
i
]
×
(
n
/
i
)
\small powFun[i] \times (n / i)
powFun[i]×(n/i)
)
\small)
)。
AC代码
//优化#pragma GCC optimize(2)//C#include<string.h>#include<stdio.h>#include<stdlib.h>#include<math.h>//C++#include<unordered_map>#include<algorithm>#include<iostream>#include<istream>#include<iomanip>#include<climits>#include<cstdio>#include<string>#include<vector>#include<cmath>#include<queue>#include<stack>#include<map>#include<set>//宏定义#define N 1010#define DoIdo main//#define scanf scanf_s#define it set<ll>::iterator//定义+命名空间typedeflonglong ll;typedefunsignedlonglong ull;const ll mod =1e9+7;const ll INF =1e18;constint maxn =1e7+10;usingnamespace std;//全局变量
ll n, k;bool vis[maxn];
ll powFun[maxn];
ll prime[maxn], cnt =0;//函数区
ll max(ll a, ll b){return a > b ? a : b;}
ll min(ll a, ll b){return a < b ? a : b;}
ll quick_pow(ll a, ll b){
ll res =1;while(b){if(b &1){
res =(res * a)% mod;}
a =(a * a)% mod;
b >>=1;}return res;}voidget_powFun(const ll n =1e7){
powFun[1]=1;for(ll i =2; i <= n; i++){if(!vis[i]){
prime[cnt++]= i;
powFun[i]=quick_pow(i, k);}for(ll j =0; j < cnt && i * prime[j]<= n; j++){
vis[i * prime[j]]=1;
powFun[i * prime[j]]=(powFun[i]* powFun[prime[j]])% mod;if(i % prime[j]==0)break;}}}//主函数intDoIdo(){
ios::sync_with_stdio(false);
cin.tie(NULL), cout.tie(NULL);
cin >> n >> k;get_powFun();
ll ans =0;for(ll i =1; i <= n; i++){
ans =(ans + powFun[i]*(n / i))% mod;}
cout << ans << endl;return0;}//分割线---------------------------------QWQ/*
*/