暑假假期训练总结-1

一、快速幂

快速幂求(a^b)%n。

1.递归实现

int quickpow(int a,int b,int c)
{
    if(b==1) return a;
    if(b%2==0)
    {
        int t=quickpow(a,b/2,n);
        return t*t%n;
    }
    else 
    {
        int t=quickpow(a,b/2,n);
        t=t*t%n;
        t=t*a%n;
        return t;
    }
}

2.非递归实现

int quickpow(int a,int b,int c)
{
    int ret=1;
    while(b)
    {
        if(b%2==1) ret=ret*a%n;
        a=a*a%n;
        b=b/2;
    }
    return ret;
}

二、最大公约数

1.辗转相除法求最大公约数,又称欧几里得算法

int GCD(int x,int y)
{
    return y==? x:GCD(y,x%y);
}

2.二进制算法

改进提高GCD的效率,去除因子中的2来降低常数

#include<iostream>
#include<cstdio>
using namespace std;

inline int gcd(int x,int y)
{
    int i,j;
    if(x==0) return y;
    if(y==0) return x;
    for(i=0;0==(x&1);++i) x>>=1;
    for(j=0;0==(y&1);++j) y>>=1;//去掉所有的2
    if(i<j) i=j;
    while(1)
    {
        if(x<y) {int c=x;x=y;y=c;} 

        if(0==(x-=y)) return y<<i;
        while(0==(x&1)) x>>=1;//去掉所有的2
    }
}

int main()
{
    int m=gcd(25,5);
    cout<<m<<endl;
    return 0;
}

3.扩展欧几里得算法

在已知的(a,b)时,用扩展欧几里得算法求解一组(p,q),使得p*a+q*b=GCD(a,b)

因为: a*x1+b*y1=gcd(a,b) = gcd(b,a%b)

            gcd(b,a%b) =b*x2+(a%b)*y2;

所以:a*x1+b*y1=b*x2+(a%b)*y2 = b*x2 +(a-[a/b]*b)*y2;

          =a*y2+b(x2-[a/b]*y2)

即得到: {x1=y2 ; y1= x2-[a/b]*y2}

#include<cstdio>
using namespace std;

int exgcd(int a,int b,int &x,int &y)
{
    if(b==0)
    {
        x=1;
        y=0;
        return a;
    }

    int r=exgcd(b,a%b,x,y);
    int t=x;
    x=y;
    y=t-(a/b)*y;
    return r;
}

int main()
{
    int a,b,x,y,z;
    scanf("%d%d",&a,&b);
    z=exgcd(a,b,x,y);
    printf("%d %d %d\n",z,x,y);
    return 0;
}

4.线性同余方程

(1)对于方程a*x+b*y=c 有整数解的必要条件是c%GCD(a,b)=0;

         先利用扩展欧几里得算法求出一组 x0,y0,a*x0+b*y0=GCD(a,b);将该式乘以c/GCD(a,b),找到方程的一个解

(2)若GCD(a,b)=1 ,x0,y0为方程的一组解,

        方程的额任意一组解可表示为:x=x0+b*t,y=y0+a*t

        t=b/GCD(a,b),             x=(x%t+t)%t(+-t调整x的正负);

5.最小公倍数

a,b的最大公约数乘以他们的最小公倍数就等于a*b;

最大公约数=(a*b)/gcd(a,b);

6.欧几里得的游戏:

分析两种情况之后:首先拿到A/B>1的人是必胜的,如果A/B一直等于1 就要看有多少局游戏了

三、逆元

1.a,b互质,即GCD(a,b)=1; 可以转化为:a*x+b*y=1再用拓展欧几里得算法求出x。

2.sumdiv 求A^B的所有因子之和

题解链接:

其中:用递归二分求等比数列,用反复平方法计算p^n

四、中国剩余定理

用来求解“模线性方程组”的解

a≡b[1](mod w[1])

a≡b[2](mod w[2])

……

其中W数组中的数互质,求a的值,

解有不同周期的N件事,同在1天内发生,这一天最短什么时候到来

例如题目:Biorhys

假设一年的第N天达到峰值,则下次到达峰值的时间应该为N+T*k(T是周期,k是任意正整数)

三个峰值同时出现的那一天应该满足:

S=N1+T1*k1=N2+T2*k2=N3+t3*k3;

S≡N1(modt1);S≡N2(modT2);S≡N3(modT3);

猜你喜欢

转载自blog.csdn.net/wentong_Xu/article/details/81291856
今日推荐