20天集训——day4

今天依旧是讲数论。我觉得我这两天没太大的收获,至少写代码的能力没啥长进。数论大部分是和数学有关的,理解起来困难,转化为程序理解更难。我都是老师解释的大部分能听懂,一变为程序就一脸懵逼。所以那些求……的模板都是死记硬背的。昨天讲的是进制,回文数,整除一些的。今天讲的是各种定理的解释和代码。

今天讲了两个求素数的方法:埃式筛法和线性筛法。

const int maxn=100000;//埃式筛法
bool isprime[maxn];
void searchPrime(int n)
{
    memset(isprime,true,sizeof(isprime));//=isprime[maxn]={1}
 isprime[1]=false;
 for(i=2;i<=n;i++)
  if(isprime(i))
  {
     j=i*i;
        while(j<=maxn)
        {
      isprime[j]=false;
   j+=i;
  }
  }
}

void seive(int Max)//线性筛法
{   
    memset(isPrime,true,sizeof(isPrime));
    isPrime[0]=false;     
 isPrime[1]=false;
    for(int i=2;i<=Max;i++)//遍历筛去所有最大因数是i的合数
     {
     if(isPrime[i])
   prime[++total]=i;//把素数记录下来
             //遍历已知素数表中比i的最小素因数小的素数,并筛去合数
        for(int j=1;j<=total&&i*prime[j]<=Max;j++)
        {
      isPrime[i*prime[j]]=false;
            if((i%prime[j])==0) break;//找到i的最小素因数
        }
     }
}

这些模板算法我都理解不全。尽管有比较详尽的注释说明,但依旧不太明白,这些模板还要默写所以我都死记硬背背下来。
还有一个欧拉函数这比前两个素数的什么筛法还要难理解。

#include<bits/stdc++.h>
using namespace std;
int main()
{
 int k=2,s=n;//求欧拉函数(n)
 while(k*k<=n)
 {
  if(n%k==0)
  {
   s=s*(k-1)/k;
   while(n%k==0)
    n/=k;
  }
  k++;
 }
 if(n>1)
  s*=(n-1)/n;
 cout<<s;
}


for(int i=2;i<=n;i++)//求欧拉函数(i),i=1~n
{
 if(!IsPrime[i])
    { 
  prime[++cnt]=i; 
  phi[i]=i-1;
 }
 for(int j=1;j<=cnt;j++)
    {
  if(prime[j]*i>n)  break;
        Isprime[prime[j]*i]=1;
       if (i%prime[j]==0)
        {
   phi[i*prime[j]]=phi[i]*prime[j];
   break;
  } //i含prime[j]因子
        else
         phi[i*prime[j]]=phi[i]*(prime[j]-1); //i不含prime[j]因子
    }
}

上面是这一天较重要的几段程序。下面是没那么重要但也很常用的模板

k=2;//n的质因数分解
while (k*k<=a)
{
    if(a%k==0)
    while(a%k==0)
    {
        a/=k; …//对因子重数的其他处理
    }
    k++;
}
if (a>1) …//再对分解最后的那个质数进行处理

int nums(int n)//求n的约数个数
{
    int k, res, p;
    k=2; res=1;
    while (k*k<=a)
    {
    p=1;
       while (n%k==0)
    {
       a/=k; p++;
    }
       res*=p;
       k++;
    }
    if(a>1) res*=2;//只剩一个最大的质因子
    return res;
}

int sum(int n)//求n的约数和
{
    int k, res, tmp;
    k=2; res=1;
    while (k*k<=a)
    {
    tmp=1;
       while (n%k==0)
    {
       a/=k; tmp=tmp*k+1;
    }
       res*=tmp;
       k++;
    }
    if (a>1)  res*=(1+a);//只剩一个最大的质因子
    return res;
}

今天的收获大概就是这些还未理解的几个模板吧




猜你喜欢

转载自blog.csdn.net/wangzhuojia/article/details/80953666