2019年第十届蓝桥杯决赛(国赛) C++大学A组 D题 序列求和【全网找不到的题解?】
題面
試題 D: 序列求和
本題總分:10 分
【問題描述】
學習了約數后,小明對于約數很好奇,他發現,給定一個正整數 t,總是可以找到含有 t 個約數的整數。小明對于含有 t 個約數的最小數非常感興趣,并把它定義為 S t S_t St?。
例如 S 1 = 1 S_1 = 1 S1?=1, S 2 = 2 S_2 = 2 S2?=2, S 3 = 4 S_3 = 4 S3?=4, S 4 = 6 S_4 = 6 S4?=6,· · · 。
現在小明想知道,前 60 個 S i S_i Si? 的和是多少?即 S 1 S_1 S1? + S 2 S_2 S2? + · · · + S 60 S_{60} S60? 是多少?
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
思路
在網上找了半天都沒有這題的正確題解,決賽A組的填空題都沒人寫題解?好吧,然而我也不會,寫了個暴力,打表到50就不行了,看來答案至少到long long了。
請教了搞數學的隊友yz @yingyingying002(yz tql),告訴我直接dfs搜索,分解數求值。
舉個例子,求因子數為12的最小數。
12 = 6 ? 2 ; a n s = 2 5 ? 3 1 12 = 6*2;ans=2^5*3^1 12=6?2;ans=25?31
? = 3 ? 2 ? 2 ; a n s = 2 2 ? 3 1 ? 5 1 = 3*2*2;ans=2^2*3^1*5^1 =3?2?2;ans=22?31?51
? = 4 ? 3 ; a n s = 2 3 ? 3 2 = 4*3;ans=2^3*3^2 =4?3;ans=23?32
? = 2 ? 2 ? 3 ; a n s = 2 2 ? 3 1 ? 5 1 = 2*2*3;ans=2^2*3^1*5^1 =2?2?3;ans=22?31?51
12有以上4種分解方法,每個乘數-1就是要求的數分解后的質數的冪次(唯一分解定理),接下來考慮如何分配這些冪次給質數使得數最小?顯然貪心。我們看最后一種分解方法,12=2*2*3,將其降序排序,3,2,2,再減一為2,1,1,那么顯然 2 2 ? 3 1 ? 5 1 2^2*3^1*5^1 22?31?51能夠讓數盡量小并且滿足因子數為12。
最后,我們dfs搜出所有的分解情況,然后其中最小的數。
另外,特判因子數為質數,比如因子數是13,減一是12,這個冪次全部分配給2,能得到的最小數是212,滿足因子數是13。
代碼
#include <bits/stdc++.h> using namespace std; typedef unsigned long long ll; const ll N=1e5,inf=1e18; bool vis[N+10]; ll prime[N+10],tot=0,mi; void get_prime() // 素數篩 {memset(vis,1,sizeof(vis));vis[0]=vis[1]=0;for(int i=2;i<=N;i++){if(vis[i])prime[tot++]=i;for(int j=0;j<tot&&i*prime[j]<=N;j++){vis[i*prime[j]]=0;if(i%prime[j]==0)break;}} } ll qpow(ll a,ll b) // 快速冪 {ll s=1;while(b){if(b&1)s=s*a;b/=2;a*=a;}return s; } ll dfs(ll x,vector<ll>g) // 將x分解成若干個數的乘積 {if(vis[x]||x==1)return qpow(2,x-1); // 特判質數和1for(ll i=2;i*i<=x;i++){if(x%i==0){ll t=x/i; // 大的那個數 g.push_back(i);// 更新mi vector<ll>tmp=g;tmp.push_back(t); sort(tmp.begin(),tmp.end(),greater<ll>());ll s=1;for(int j=0;j<tmp.size();j++)s*=qpow(prime[j],tmp[j]-1); mi=min(mi,s);dfs(t,g);g.pop_back();}}return mi; } int main() {ios::sync_with_stdio(false);get_prime();ll ans=0;vector<ll>g;for(int i=1;i<=60;i++){mi=inf;g.clear();ll ts=dfs(i,g);ans+=ts;//printf("i=%d ts=%lld ans=%lld\n",i,ts,ans);}printf("%lld\n",ans);return 0; }答案:292809912969717649
總結
以上是生活随笔為你收集整理的2019年第十届蓝桥杯决赛(国赛) C++大学A组 D题 序列求和【全网找不到的题解?】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【程序设计】多线程
- 下一篇: s3c2440移植MQTT