題目描述
輸入格式
輸出格式
樣例
數據范圍與提示
Solution:
本題ZYYS。。。
直接枚舉顯然不行,我們考慮改為求$n$的某一因子$d$在整個函數中的貢獻是多少。
套上數論分塊的思想,一個因子$d$對式子的貢獻是$\lfloor{\frac{n}{d}}\rfloor\times d^k$。
這樣我們需要處理的就是$d^k$,直接$O(n\log k)$快速冪求出每個因子的冪是肯定不行的,因為$n$是$10^7$,直接會T。
那么還是考慮優化,我們發現,每個數都能唯一分解,而在求冪時會有重復計算的質因子冪。於是,我們考慮線篩,這樣就可以用每個數的最小質因子冪去算它的冪了,那么整個過程只會對$n\leq 10^7$內的質數進行快速冪,最后復雜度就成了$\sqrt n \log k$,完全可行。
所以最后就只需再$O(n)$掃一遍因子累加貢獻求和就好了。
代碼:
#include<iostream> #define il inline #define ll long long #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++) #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--) #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)>(b)?(b):(a)) using namespace std; const int N=1e7,mod=1e9+7; int prime[N+5],ans,cnt,n,k,sum[N+5]; bool isprime[N+5]; il int fast(ll s,ll k){ ll ans=1; while(k){ if(k&1)ans=ans*s%mod; k>>=1; s=s*s%mod; } return ans; } il void init(){ sum[1]=1; For(i,2,n+1) { if(!isprime[i]) prime[++cnt]=i,sum[i]=fast(i,k); for(int j=1;j<=cnt&&prime[j]*i<=n+1;j++){ isprime[prime[j]*i]=1; sum[prime[j]*i]=sum[i]*1ll*sum[prime[j]]%mod; if(i%prime[j]==0)break; } } } int main(){ ios::sync_with_stdio(0); cin>>n>>k; init(); For(i,1,n) ans=(ans+1ll*(n/i)*sum[i])%mod; cout<<ans; return 0; }
