cf1208G Polygons 欧拉函数
鏈接
cf
給你兩個(gè)正整數(shù)\(n\)和\(k\),詢問(wèn)在一個(gè)圓上你最少需要幾個(gè)點(diǎn)構(gòu)才能造出\(k\)個(gè)邊數(shù)小于等于\(n\)的正多邊形
思路
深受迫害,所以寫的詳細(xì)一點(diǎn),不會(huì)請(qǐng)留言。
性質(zhì)1
考慮加進(jìn)一個(gè)\(x\)邊形。那么他的因子\(d\)一定在他之前加進(jìn)來(lái)了.
因?yàn)?span id="ozvdkddzhkzd" class="math inline">\(d\)可以完全由\(x\)的點(diǎn)表現(xiàn)出來(lái)。
如果沒加\(d\),那么加\(d\)顯然比加\(x\)優(yōu)秀(顯然)。
性質(zhì)2
兩個(gè)圖形,讓他們盡量多的重合些點(diǎn)是好的。
那兩個(gè)圖形能重合多少點(diǎn)呢?答案顯然是固定的。
兩個(gè)圖形讓他們一個(gè)點(diǎn)重合,即可得到最好的。
因?yàn)槭钦噙呅?#xff0c;所以隨便重合一個(gè)點(diǎn),重合的情況都是一樣的。
即最優(yōu)的答案。
所以我們加入的\(k\)個(gè)正多邊形都重合到一個(gè)點(diǎn)上,設(shè)這個(gè)點(diǎn)為\(0\)點(diǎn)。
聯(lián)系起來(lái)
\(x\)在圓上,假設(shè)他的點(diǎn)為\(\frac{0}{x},\frac{1}{x}……\frac{x-1}{x}\)
由\(part2\)可以知道,0這個(gè)點(diǎn)上每個(gè)圖形都會(huì)經(jīng)過(guò)。
由\(part1\)可以知道\(x\)的點(diǎn)上,他的因子在之前就會(huì)加入,所以他的因子及其倍數(shù)都是原先就有的(被覆蓋過(guò))。
這個(gè)過(guò)程就是類似于暴力篩\(phi\)的過(guò)程,所以剩下的就是與他互質(zhì)的數(shù)。
所以一個(gè)正\(x\)邊形的貢獻(xiàn)就是\(phi(x)\).
找出\(k\)個(gè)最小的\(phi\)就行了
其實(shí)這個(gè)題就是俄羅斯數(shù)學(xué)競(jìng)賽的題目....我同桌給我講過(guò)類似的證明,忘記了(菜)。
代碼
因?yàn)?,2不是正x邊形,所以不能選為k變形
#include <bits/stdc++.h> using namespace std; const int _=1e6+7,limit=1e6; int phi[_]; void Euler() {for(int i=1;i<=limit;++i) phi[i]=i;for(int i=2;i<=limit;++i) {if(phi[i]==i) {phi[i]=i-1;for(int j=i+i;j<=limit;j+=i)phi[j]=(phi[j]/i)*(i-1);}} } std::vector<int> ans; int main() {Euler();int n,k;cin>>n>>k;if(k==1) return puts("3"),0;for(int i=3;i<=n;++i) ans.push_back(phi[i]);sort(ans.begin(),ans.end());long long tot=0;for(int i=0;i<k;++i) tot+=ans[i];cout<<tot+2<<"\n";return 0; }轉(zhuǎn)載于:https://www.cnblogs.com/dsrdsr/p/11428182.html
總結(jié)
以上是生活随笔為你收集整理的cf1208G Polygons 欧拉函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: luoguP4213 【模板】杜教筛(S
- 下一篇: 解读阿里巴巴集团的“大中台、小前台”组织