YbtOJ-选点构形【欧拉函数】

1|0正题

题目链接:https://www.ybtoj.com.cn/contest/351/problem/1


1|1题目大意

一个圆上,你需要在3n中选出k个作为ai,然后再圆上选择最少的点使得对于每个ai你都能用选出的点连成一个正ai边形。

k+2n106


1|2解题思路

首先我们固定一个0点因为肯定所有的正ai边形都交于一个点。

然后考虑对于一个ai,我们需要的点就是1ai×k(0k<ai)

注意到一个ai如果存在一个aj=k×ai那么ai就不会产生贡献。反过来说aj的贡献会减少ai

而我们肯定是优先选择ai的,也就是说aj选择当且仅当它的所有约数都被选择,而此时aj产生的贡献恰好就是φ(aj)(因为所有aj约数产生的贡献和为aj,我们可以视为它们的贡献都单独为φ(x)

那么我们可以把3n按照φ排序从小到大加就好了。

至于1,2,特判一下比较小的情况就可以了,k比较大时显然1,2会被选上去,需要多选2个。

时间复杂度:O(nlogn)


1|3code

#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; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15916119.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
历史上的今天:
2021-02-20 P4345-[SHOI2015]超能粒子炮·改【Lucas定理,类欧】
2021-02-20 P4389-付公主的背包【生成函数,多项式exp】
2021-02-20 CF848E-Days of Floral Colours【dp,分治NTT】
2021-02-20 YbtOJ#853-平面标记【整体二分,凸壳】
2021-02-20 51nod1600-Simple KMP【SAM,树链剖分】
点击右上角即可分享
微信分享提示