YbtOJ-选点构形【欧拉函数】
正題
題目鏈接:https://www.ybtoj.com.cn/contest/351/problem/1
題目大意
一個(gè)圓上,你需要在3~n3\sim n3~n中選出kkk個(gè)作為aia_iai?,然后再圓上選擇最少的點(diǎn)使得對(duì)于每個(gè)aia_iai?你都能用選出的點(diǎn)連成一個(gè)正aia_iai?邊形。
k+2≤n≤106k+2\leq n\leq 10^6k+2≤n≤106
解題思路
首先我們固定一個(gè)000點(diǎn)因?yàn)榭隙ㄋ械恼?span id="ozvdkddzhkzd" class="katex--inline">aia_iai?邊形都交于一個(gè)點(diǎn)。
然后考慮對(duì)于一個(gè)aia_iai?,我們需要的點(diǎn)就是1ai×k(0≤k<ai)\frac{1}{a_i}\times k(0\leq k<a_i)ai?1?×k(0≤k<ai?)。
注意到一個(gè)aia_iai?如果存在一個(gè)aj=k×aia_j=k\times a_iaj?=k×ai?那么aia_iai?就不會(huì)產(chǎn)生貢獻(xiàn)。反過(guò)來(lái)說(shuō)aja_jaj?的貢獻(xiàn)會(huì)減少aia_iai?。
而我們肯定是優(yōu)先選擇aia_iai?的,也就是說(shuō)aja_jaj?選擇當(dāng)且僅當(dāng)它的所有約數(shù)都被選擇,而此時(shí)aja_jaj?產(chǎn)生的貢獻(xiàn)恰好就是φ(aj)\varphi(a_j)φ(aj?)(因?yàn)樗?span id="ozvdkddzhkzd" class="katex--inline">aja_jaj?約數(shù)產(chǎn)生的貢獻(xiàn)和為aja_jaj?,我們可以視為它們的貢獻(xiàn)都單獨(dú)為φ(x)\varphi(x)φ(x))
那么我們可以把3~n3\sim n3~n按照φ\(chéng)varphiφ排序從小到大加就好了。
至于1,21,21,2,特判一下比較小的情況就可以了,kkk比較大時(shí)顯然1,21,21,2會(huì)被選上去,需要多選222個(gè)。
時(shí)間復(fù)雜度:O(nlog?n)O(n\log n)O(nlogn)
code
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int N=1e6+10; int n,k,cnt,phi[N],pri[N/10]; bool v[N]; int main() {freopen("point.in","r",stdin); freopen("point.out","w",stdout);scanf("%d%d",&n,&k);if(k==1)return puts("3")&0;if(k==2)return puts("6")&0;phi[1]=1;for(int i=2;i<=n;i++){if(!v[i])phi[i]=i-1,pri[++cnt]=i;for(int j=1;j<=cnt&&i*pri[j]<=n;j++){v[i*pri[j]]=1;if(i%pri[j]==0){phi[i*pri[j]]=phi[i]*pri[j];break;}phi[i*pri[j]]=phi[i]*phi[pri[j]];}}sort(phi+1,phi+1+n);long long ans=0;for(int i=1;i<=k+2;i++)ans+=phi[i];printf("%lld\n",ans);return 0; }總結(jié)
以上是生活随笔為你收集整理的YbtOJ-选点构形【欧拉函数】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: CF1063F-String Journ
- 下一篇: Lucid 宣布采用 NACS 标准,旗