zoukankan      html  css  js  c++  java
  • 欧拉筛与欧拉函数

    如今我才知道欧拉筛和欧拉函数之间的关系。之前我欧拉函数离线打表一直是n²,亏我一直不T。

    先放个纯欧拉筛。prime[1~cnt]记录了cnt个素数,而vis[i]=false表示这个数是素数。

     1 const int MAXN=3000001;
     2 int prime[MAXN];//保存已经求出的素数
     3 bool vis[MAXN];//判断是不是素数
     4 int Prime(int n)
     5 {
     6     int cnt=0;
     7     memset(vis,0,sizeof(vis)); //vis[]=0指是素数
     8     for(int i=2;i<n;i++)
     9     {
    10         if(!vis[i])
    11         prime[cnt++]=i;
    12         for(int j=0;j<cnt&&i*prime[j]<n;j++)
    13         {
    14             vis[i*prime[j]]=1;
    15             if(i%prime[j]==0)//欧拉筛法的精髓之处,目的是为了不重复筛除数据
    16             break;
    17         }
    18     }
    19     return cnt;//返回小于n的素数的个数
    20 }

    再放个线性的欧拉函数板子,内置欧拉筛。

    phi[i]表示i的欧拉函数。

     1 const int N=1e7;
     2 int phi[N+10],prime[N+10],tot,ans;
     3 bool mark[N+10];
     4 void getphi()    {
     5    int i,j;
     6    phi[1]=1;
     7    for(i=2;i<=N;i++){
     8        if(!mark[i]){
     9              prime[++tot]=i;//筛素数的时候首先会判断i是否是素数。
    10              phi[i]=i-1;//当 i 是素数时 phi[i]=i-1
    11              }
    12        for(j=1;j<=tot;j++){
    13           if(i*prime[j]>N)  break;
    14           mark[i*prime[j]]=1;//确定i*prime[j]不是素数
    15           if(i%prime[j]==0){//接着我们会看prime[j]是否是i的约数
    16              phi[i*prime[j]]=phi[i]*prime[j];break;
    17           }
    18           else phi[i*prime[j]]=phi[i]*(prime[j]-1);//其实这里prime[j]-1就是phi[prime[j]],利用了欧拉函数的积性
    19        }
    20    }
    21 }
    22 //调用时,给出getphi();即可,mark[i]是false说明是素数,否则是合数
  • 相关阅读:
    【leetcode】Maximum Subarray
    【USACO】
    【leetcode】Remove Duplicates from Sorted Array
    【leetcode】Path Sum II
    【leetcode】Swap Nodes in Pairs
    【leetcode】Word Ladder
    【leetcode】Copy List with Random Pointer
    【leetcode】Longest Palindromic Substring
    #ifdef #endif #if #endif
    tar [options] [list of file]
  • 原文地址:https://www.cnblogs.com/St-Lovaer/p/13457877.html
Copyright © 2011-2022 走看看