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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

贡献思想 + 数论 + 思维(例题 Problem J. Prime Game)

發布時間:2025/4/16 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 贡献思想 + 数论 + 思维(例题 Problem J. Prime Game) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

首先說一下貢獻的思想:

舉個例子:已知有n個數,從?,求?中所有質因數出現的個數。

假設當前數為??6, 7, 5, 5, 4, 9, 9, 1, 8, 12

  • 首先寫出他每個數的質因數:
每個數的質因數分解
67554991812
2,3755233022,3
  • 那么求任意區間質因數的個數,就可以轉化為求解每個數在任意區間所作的貢獻度。
求解貢獻度
序號12345678910
ai67554991812
質因數2,3755233022,3
貢獻度(10) + (10)9 + 98 + 8 + 876 + 6 + 6 + 65 + 5 + 5 + 5402+2+2+21 + (1 + 2)

(求解貢獻度時要注意前面已經出現和計算過的數字不在計算,防止重復。如:質因數2的貢獻,在序號為1處出現質因數為2,此時他的貢獻度為:

? ? ? ? [1, 1] , [1, 2], [1, 3] , [1, 4], [1, 5], [1, 6], [1, 7], [1, 8], [1, 9],? [1, 10]

在序號為5處出現質因數2,此時他的貢獻度為:

? ? ? ? [1, 5](這個已經被計算過一次,舍去)

? ? ? ? ? ?實際貢獻度:[5, 5] , [5, 6] , [5, 7] , [5, 8] , [5, 9] , [5, 10]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[2, 5] , [2, 6] , [2, 7] , [2, 8] , [2, 9] , [2 , 10]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[3, 5] , [3, 6] ,?[3, 7] , [3, 8] , [3, 9] ,?[3, 10]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[4, 5] , [4, 6] , [4, 7] , [4, 8] , [4, 9] ,?[4, 10]

在序號為9處出現質因數2, 此時他的貢獻度為:

? ? ? ? ? 實際貢獻度: [9, 9] , [9, 10]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[6, 9] , [6, 10]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[7, 9] , [7, 10]

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?[8, 9] , [8, 10]

在序號為10處出現質因數2,此時他的貢獻度為:

? ? ? ? 實際貢獻度:? [10, 10]

好處:

如果直接使用暴力的算法的話,時間復雜度為,避免不了求區間的情況,但如果使用求貢獻度的思維去求,可以在O(n)的時間復雜度內完成

然后就是求解每個數的質因數分解:

可以直接用埃式篩法來得到:

const int maxn = 1e6+5; int vis[maxn]; vector<int>v[maxn]; void init(){memset(vis, 0, sizeof(vis));for(int i = 2; i < maxn; i++){if(!vis[i]){v[i].push_back(i);for(int j = 2*i; j < maxn; j += i){vis[j] = 1;v[j].push_back(i);}}} }

然后就很好求解了。。。。。。。

?

一道例題:

?

這道題就是一道求貢獻度的題,只要理解上面就很好求解了:

#include<bits/stdc++.h>using namespace std; typedef long long LL;const int maxn = 1e6+5; int vis[maxn]; vector<int>v[maxn]; vector<int>pos[maxn]; int n; int a[maxn];void init(){memset(vis, 0, sizeof(vis));for(int i = 2; i < maxn; i++){if(!vis[i]){v[i].push_back(i);for(int j = 2*i; j < maxn; j += i){vis[j] = 1;v[j].push_back(i);}}} }int main() {init();scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%d", &a[i]);LL ans = 0;for(int i = 1; i <= n; i++){if(a[i] == 1) continue;int tmpnum = v[a[i]].size();for(int j = 0; j < tmpnum; j++){int now = v[a[i]][j];if(pos[now].size() == 0){ans += 1LL * (n - i + 1) * i;pos[now].push_back(i);}else{vector<int>::iterator it = pos[now].end(); it--;int tmppos = *it;ans += 1LL * (n - i + 1) * (i - tmppos);pos[now].push_back(i);}}}printf("%lld\n", ans);return 0; }

?

總結

以上是生活随笔為你收集整理的贡献思想 + 数论 + 思维(例题 Problem J. Prime Game)的全部內容,希望文章能夠幫你解決所遇到的問題。

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