• 欧拉函数——最大公约数(gcd+筛质数+欧拉函数)


    传送门:220. 最大公约数 - AcWing题库

    思路:

    题目要求的gcd(x,y)=p;(这里设p为质数),可以得到 gcd(x/p,y/p)=1; 

    题目转化为在1~N/p中找到a,b满足gcd(a,b)=1;因为最后要转化为gcd(a*p,b*p)=p;

    到这里题目转化成为求1~N的每个数的欧拉函数。以及求出N的所有质因数p。

    第一步:用埃氏筛法求1~N的欧拉函数以及N的质因数(N有可能是质数,所以1~N都要求欧拉函数)

    第二步:累加欧拉前缀值sum[i],优化计算。

    第三步:对每一个质数pi,求出N/pi , 累加sum[N/pi]*2+1。 

    注意:题目的数对是无序的,所以答案要乘2,同时,当x==y==p时,这个数对(x,y)也成立,所以要加1.

    埃氏筛法代码:

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. typedef pair<int,int>PII;
    9. typedef long long ll;
    10. const int N=1e7+10,M=1e7+10;
    11. int phi[N],cnt;
    12. int primes[N];
    13. int n;
    14. ll sum[N];
    15. void get()
    16. {
    17. for(int i=2;i<=n;i++) phi[i]=i;
    18. for(int i=2;i<=n;i++)
    19. {
    20. if(phi[i]==i)
    21. {
    22. primes[++cnt]=i;
    23. for(int j=i;j<=n;j+=i)
    24. phi[j]=phi[j]/i*(i-1);
    25. }
    26. }
    27. }
    28. int main()
    29. {
    30. scanf("%d",&n);
    31. get();
    32. ll ans=0;
    33. for(int i=2;i<=n;i++)
    34. sum[i]+=sum[i-1]+phi[i];
    35. for(int i=1;i<=cnt;i++)
    36. {
    37. int t=n/primes[i];
    38. ans+=sum[t]*2+1;
    39. }
    40. cout<
    41. return 0;
    42. }

    线筛法代码:

    思路:

    由欧拉函数的两个性质。

    1.设p是质数,若n%p==0且n%(p^2)==0,则phi[n]=phi[n/p]*p;

    2.设p是质数,若n%p==0但n%(p^2)!=0,则phi[n]=phi[n/p]*(p-1);

    线筛法中,每个合数都只会被最小的质因数筛一次,此时可以做上面的判断???

    区别:这里phi[i]初始化为i-1,因为这里是采用递推求值,埃氏筛是根据公式求值

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. using namespace std;
    8. typedef pair<int,int>PII;
    9. typedef long long ll;
    10. const int N=1e7+10,M=1e7+10;
    11. int phi[N],cnt;
    12. int primes[N];
    13. bool st[N];
    14. int n;
    15. ll sum[N];
    16. void get()
    17. {
    18. phi[1]=1;
    19. for(int i=2;i<=n;i++)
    20. {
    21. if(!st[i])
    22. {
    23. primes[++cnt]=i;
    24. phi[i]=i-1;
    25. }
    26. for(int j=1;primes[j]<=n/i;j++)
    27. {
    28. int t=primes[j]*i;
    29. st[t]=true;
    30. if(i%primes[j]==0)
    31. {
    32. phi[t]=phi[i]*primes[j];
    33. break;
    34. }else{
    35. phi[t]=phi[i]*(primes[j]-1);
    36. }
    37. }
    38. }
    39. }
    40. int main()
    41. {
    42. scanf("%d",&n);
    43. get();
    44. ll ans=0;
    45. for(int i=2;i<=n;i++)
    46. sum[i]+=sum[i-1]+phi[i];
    47. for(int i=1;i<=cnt;i++)
    48. {
    49. int t=n/primes[i];
    50. ans+=sum[t]*2+1;
    51. }
    52. cout<
    53. return 0;
    54. }

  • 相关阅读:
    卸载Erlang和RabbitMQ
    初识C语言
    Go&Java算法之同构字符串
    无参函数声明 函数的使用范围
    【k8s】ingress-nginx通过header路由到不同后端
    从 Uber 数据泄露事件我们可以学到什么?
    力扣 234. 回文链表
    IntelliJ IDEA 介绍、安装、配置优化与快捷键大全
    记录一个在写项目中遇到的Maven依赖无法导入的问题
    人才网招聘网程序人才招聘系统/招聘APP/H5/求职招聘兼职/招聘企业职位求职招聘小程序
  • 原文地址:https://blog.csdn.net/m0_62327332/article/details/126685423