大一寒假集训2020.1.4 //gcd&&lcm&&快速幂取模

大一寒假集训2020.1.4

GCD&&LCM

取模运算的运算规则
(a + b) % p = (a % p + b % p) % p
(a - b) % p = (a % p - b % p) % p
(a * b) % p = (a % p * b % p) % p
a ^ b % p = ((a % p)^b) % p

最大公约数 一般使用欧几里得算法;即辗转相除法。
最小公倍数的求法是在最大公约数基础上得来。
lcm(x,y)=x*y/gcd(x,y)

最大公约数和最小公倍数

辗转相除求最大公约数

#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
    int r;
    r = a % b;
    while (r)
    {
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}
int main()
{
    int a, b;
    while (cin >> a >> b)
    {
        int gy, gb;
        gy = gcd(a, b);
        gb = a / gy * b;
        cout << gy << " " << gb << endl;
    }
    return 0;
}

又见GCD

已知一个数,和最大公约数求另一个数。
暴力写法,循环遍历

#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
    int r;
    r = a % b;
    while (r)
    {
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}

int main()
{
    int a, r;
    while (cin >> a >> r)
    {
        for (int i = 1; 1; i++)
        {
            if (gcd(a, i) == r && i != r)         //找到退出。
            {
                cout << i << endl;
                break;
            }
        }
    }
    return 0;
}

多个数的最大公约数

在单个基础上,多次使用GCD

#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
    int r;
    r = a % b;
    while (r)
    {
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}
int dgcd(long long  a[],long long  n)
{
    int b=a[0];
    for(int i=1;i<n;i++)
    {
        b=gcd(b,a[i]);
    }
    return b;
}
int main()
{
    long long n;
    long long a[100];
    long long gy;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        gy=dgcd(a,n);
        cout<<gy<<endl;
    }
    return 0;
}

多个数的最小公倍数

与上同理,多个数使用LCM

#include<bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
    int r;
    r = a % b;
    while (r)
    {
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}
int lcm(int a,int b)
{
    int gb;
    gb=a/gcd(a,b)*b;
    return gb;
}
int dlcm(long long a[],long long n)
{
    int gb=a[0];
    for(int i=1;i<n;i++)
    {
        gb=lcm(a[i],gb);
    }
    return gb;
}
int main()
{
    long long a[100];
    long long n;
    while(cin>>n)
    {
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
        }
        long long result;
        result=dlcm(a,n);
        cout<<result<<endl;
    }
    return 0;
}

LCM&GCD

题目不难,难在优化。
直接暴力找就会TLE教做人
所以我们有技巧的暴力

#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b)
{
    long long r;
    r = a % b;
    while (r)
    {
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}

int main()
{
    long long t;
    while (scanf("%lld", &t) != EOF)
    {
        while (t--)
        {
            long long x, y;
            scanf("%lld%lld", &x, &y);
            long long ans = 0;
            long long h;
            h = x * y;
            for (int a = x; a <= y; a++)       //从x到y
            {
                if (h % a == 0)                       //满足两条条件就可知他是一种情况
                {
                    if (h / a <= y && h / a >= x && gcd(a, h / a) == x) 
                    {
                        ans++;
                    }
                }
            }
            cout << ans << endl;
        }
    }
    return 0;
}

人见人爱gcd

这是数学题,蒟蒻不会
有手写的证明过程
可以证gcd(x,y)=gcd(a,b)
然后就很简单了。
用完全平方展开

#include <bits/stdc++.h>
using namespace std;
int gcd(int a, int b)
{
    
    if(a<b)
    {
        swap(a,b);
    }
    int r;
    while (b>0)
    {
        r = a % b;
        a = b;
        b = r;
    }
    return a;
}
int main()
{
    int t;
    while (scanf("%d",&t)!=EOF)
    {
        while (t--)
        {
            int  a, b;
            int  result;
            scanf("%d %d",&a,&b);
            int  y;
            y = gcd(a, b);
            result = (a * a) - (2 * b * y);
            printf("%d\n",result);
        }
    }
    return 0;
}

高木同学的因子

这个又是个优化题。。。
需要把遍历的数据减少防TLE

#include<bits/stdc++.h>
using namespace std;
long long gcd(long  a, long b)
{
    long long r;
    r = a % b;
    while (r)
    {
        a = b;
        b = r;
        r = a % b;
    }
    return b;
}
int main()
{
    long long x,y;
    cin>>x>>y;
    long long gy;
    gy=gcd(x,y);
    int ans=0;
    for(int i=1;i*i<=gy;i++)        //i*i<=gy;
    {
        if(gy%i==0)
        {
            ans++;
        }
    }
    if(sqrt(gy)==(int)sqrt(gy))      //根号下的比较即可
    {
        ans=ans*2-1;
    }
    else
    {
        ans*=2;
    }
    cout<<ans<<endl;
    return 0;
}

快速幂取模

我们采用分治的思想来解决这种问题
当采用计算机语言时
ab=((a(b/n))n)*a(b%n)
当n=2时
ab=(a(b/2))(a(b/2))*a(b%2)
(ab)%mod=(a(b/2))%mod
(a(b/2))%mod*a(b%2)%mod
而后对a^(b/2)进行相同的操作

快速幂取模

模板题

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

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

int main()
{
    long long a, b, c;
    while (cin >> a >> b >> c)
    {
        long long h;
        h = quickmod(a, b, c);
        cout << h << endl;
    }
    return 0;
}

库特的数学题

好的,又是一道数学题,直接用给的公式递归
果断TLE糊你一脸
所以我们根据他给的公式找通项公式。
可得2*3^n;
那我就来了

#include<bits/stdc++.h>
using namespace std;
long long quickmod(long long a, long long b, long long c)
{
    int ret = 1;
    while (b)
    {
        if (b & 1)
            ret = ret * a % c;
        a = a * a % c;
        b /= 2;
    }
    return ret;
}
int main()
{
    long long n;
    long long y;
    while(cin>>n)
    {
        y=(6%1000000007)*(quickmod(3,n-1,1000000007))%1000000007;
        cout<<y<<endl;
    }
}

虽然写的丑,但是起码是过去了。

异或方程解的个数

学长好坏,出这么个题,本蒟蒻一点思路都没有

据说这题好像只要找出给的数在二进制下有几个1,就是二的几次方
那我就会了

#include <bits/stdc++.h>
using namespace std;
int main()
{
    long long n;
    int counter = 0;
    while (scanf("%lld",&n)!=EOF)
    {
        counter=0;
        for (int i = 0; i <= n; i++)
        {
            if (i == n - (n ^ i))
            {
                counter++;
            }
        }
        printf("%d\n",counter);
    }
    return 0;
}

今天写的不是题,是数学题。主要练习了对程序的优化,让程序快速高效的走大数据,不会TLE

发布了7 篇原创文章 · 获赞 0 · 访问量 1317

猜你喜欢

转载自blog.csdn.net/qq_34212975/article/details/103845902