日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

又见莫比乌斯反演

發布時間:2024/4/11 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 又见莫比乌斯反演 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目:http://acm.uestc.edu.cn/#/problem/show/811

?

題意:給定兩個正整數和,其中,,求的值,其中。

?

分析:本題是典型的莫比烏斯反演問題。那么,怎么反演呢?

???? 首先,我們枚舉的所有值,根據以前學的莫比烏斯反演,可以很容易得到

?

?????,其中

?

???? 我們設

?

???? ,那么得到,反演后得到

?

???? 所以就是

?

???? 可以看出枚舉的所有因子遞歸下去就行。。。現在的關鍵問題是如何計算。

?

?????的表達式為

?

???? 由于不大,所以可以直接用自然數冪和,而在一段連續的區間值保持不變,思路跟下面這道題差不多。

?

???? 題目:http://blog.csdn.net/acdreamers/article/details/10249611

?

??????也就是說的時間復雜度為。加上遞歸的部分,本題總的時間復雜度為。

?

?

???? 代碼:

#include <iostream> #include <string.h> #include <stdio.h> #include <math.h>using namespace std; const int N = 50000005; typedef long long LL; const LL MOD = 1000000007;LL dp[N];LL mu(LL n,int k) {LL ans = 1;for(int i=0; i<k; i++){ans *= n;ans %= MOD;}return ans; }LL calc(LL n,int k) {if(k == 1) return ((n%MOD)*((n+1)%MOD))%MOD*500000004%MOD;if(k == 2){LL a = n % MOD;LL b = (n+1) % MOD;LL c = (2*n+1) % MOD;return a*b%MOD*c%MOD*166666668%MOD;}if(k == 3){LL t = ((n%MOD)*((n+1)%MOD))%MOD*500000004%MOD;return t * t % MOD;}if(k == 4){LL t = 6*mu(n,5)%MOD + 15*mu(n,4)%MOD + 10*mu(n,3)%MOD -n%MOD;t %= MOD;t += MOD;t %= MOD;t *= 233333335;t %= MOD;return t;}if(k == 5){LL t = 2*mu(n,6)%MOD + 6*mu(n,5)%MOD + 5*mu(n,4)%MOD -mu(n,2)%MOD;t %= MOD;t += MOD;t %= MOD;t *= 83333334;t %= MOD;return t;} }LL sum(LL n,int k) {LL ans = 0;LL T = (LL)sqrt(1.0*n);for(int i=1; i<=T; i++){LL t = (n/i) % MOD;LL a = t * t % MOD;LL b = mu(i,k) * a % MOD;LL c = i * i % MOD;LL L = n/(i+1) + 1;LL R = n/i;LL d = calc(R,k) - calc(L-1,k);d %= MOD;d += MOD;d %= MOD;c = c * d % MOD;ans += b + c;ans %= MOD;}if(T*T == n)ans -= mu(T,k+2);ans %= MOD;ans += MOD;ans %= MOD;return ans; }LL dfs(LL n,int k) {if(n < N && dp[n]) return dp[n];if(n == 1) return 1;LL ans = sum(n,k);LL tmp = 0;for(LL i=1; i*i<=n; i++){if(i*i == n){tmp %= MOD;tmp += dfs(i,k);tmp %= MOD;}else{tmp %= MOD;tmp += dfs(i,k);tmp %= MOD;if(i == 1) continue;tmp += dfs(n/i,k);tmp %= MOD;}}if(n < N)dp[n] = ((ans-tmp)%MOD + MOD) % MOD;return ((ans-tmp)%MOD + MOD) % MOD; }int main() {LL n,k;memset(dp,0,sizeof(dp));scanf("%lld%lld",&n,&k);printf("%lld\n",dfs(n,k));return 0; }


?

?

?

?

總結

以上是生活随笔為你收集整理的又见莫比乌斯反演的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。