(Day6)算法复健运动for蓝桥杯-常用数学

(Day6)算法复健运动for蓝桥杯-常用数学

1. 欧几里得算法:辗转相除法(求gcd)

int gcd(int a, int b)
{
    return 0 == b ? a : gcd(b, a % b);
}

或者C++直接调用:

编译没过,说是不能是无符号数

unsigned int a=10,b=5;
cout<<__gcd(a,b);

2. 欧拉筛(求质数)

  int cnt=0;
  vis[0]=1;
  vis[1]=1;
  for(int i=2; i<=10000000; i++)
  {
      if(!vis[i])
      {
          prime[cnt++]=i;
      }
      for(int j=0;j<cnt&&(ll)i*(ll)prime[j]<=10000000;j++)
      {
          vis[i*prime[j]]=1;
          if(i%prime[j]==0)break;
      }
  }

3. 大数快速幂

ll f(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        ans=(ans*a)%mod;
        a=(a*a)%mod;
        b>>=1;
    }
    return ans;
}

4. 矩阵快速幂

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;
const int MOD=10000;

struct mat
{
    ll a[2][2];
};

mat mat_mul(mat x,mat y)//两个矩阵相乘
{
    mat res;//新的矩阵
    memset(res.a,0,sizeof(res.a));
    for(int i=0; i<2; i++)
        for(int j=0; j<2; j++)
            for(int k=0; k<2; k++)
                res.a[i][j]=(res.a[i][j]+x.a[i][k]*y.a[k][j])%MOD;
    return res;
}
void mat_pow(int n)
{
    mat c,res;
    c.a[0][0]=c.a[0][1]=c.a[1][0]=1;
    c.a[1][1]=0;
    memset(res.a,0,sizeof(res.a));
    for(int i=0; i<2; i++) res.a[i][i]=1;//初始为E
    while(n)//非常眼熟
    {
        if(n&1) res=mat_mul(res,c);
        c=mat_mul(c,c);
        n>>=1;
    }
    printf("%d\n",res.a[0][1]);
}

int main()
{
    int n;
    while(~scanf("%d",&n)&&n!=-1)
    {
        mat_pow(n);
    }
    return 0;
}

5. 逆元

a ∗ b ≡ 1 (mod p),那么 a,b 互为模 p 意义下的逆元

费马小定理:

∀a,n满足gcd(a,n)==1,则a^φ(n)≡1(mod n)

当p是质数,且a不能被p整除时,有a^(p-1)≡1(mod p)

在计算模逆元素时,通常使用费马小定理的一个特例,即对于素数p和整数a,如果a 不是 p 的倍数,则$a^{p-1} \equiv 1 \pmod{p} $。由于模逆元素的定义是乘以一个数得到1,因此我们可以将$a^{p-1}$视为a 的逆元素。

因此,当p是一个素数,且a不是p 的倍数时,我们有$ a^{p-1} \equiv 1 \pmod{p} $,这意味着a的逆元素是$a^{p-2}$。因此,我们可以使用$ a^{p-2} $来计算a的模逆元素。

这种方法在很多情况下是有效的,因为它只需要进行一次指数运算和一次模运算,相对于其他求逆元素的方法更为高效。

所以废话少说,求逆元就是,a%mod*f(b,mod-2)%mod

6. 唯一分解定理

任何一1的自然数N,如果N不为质数,都可以唯一分解成有限个质数的乘积
$N=p^a_1p_2 ^a ...p_n^a$
那么,我们由中学所学的知识所知N的正因子共有(1+a1)
(1+a2)...(1+an)个

而这些因子(不只是质因数)的和为
$(1+p_1+p_12..p_1a)(1+p_2+p_22..p_2a)$...

7.补充

把字符串格式的数字转化为int数字的函数

char s[10];
int sum=atoi(s);

memcpy:可以复制数组

int a[109];
int b[109];
memcpy(b,a,sizeof(a));
posted @   wlqtc  阅读(8)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示