C++学习之GCD&LCM&快速幂取模

2020大一寒假培训系列

  • GCD&LCM&快速幂取模
    • GCD&LCM
      • 1.1 GCD
      • 1.2 LCM
      • 1.3 素因子法
        • GCD&LCM例题1
        • GCD&LCM例题2
    • 快速幂取模
      • 快速幂取模
        • 例题1
        • 例题2
        • 例题3

GCD&LCM&快速幂取模

今天的好一些,就是数学功底要扎实。(我找通项公式找了好久。)

GCD&LCM

1.1 GCD

取最大公约数
在c++ 中有相应函数可以调用 为 __gcd()

1.2 LCM

取最小公倍数 这个没有函数 但能通过gcd函数求
如下
C++学习之GCD&LCM&快速幂取模_第1张图片
写成这样是防止数据溢出 ( a * b )

1.3 素因子法

这个方法能减少时间复杂度
C++学习之GCD&LCM&快速幂取模_第2张图片
上题

GCD&LCM例题1

GCD模板题
多个数求最大公约数

#include 
using namespace std;
int n;
long long a[12],ans;
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        for(int i=0; i>a[i];
        ans=a[0];
        for(int i=1; i

LCM模板题
同上面的代码,但要把ans=后面的换成 *ans/__gcd(ans,a[i])a[i]

GCD&LCM例题2

难题
这个题就会爆 用素因子的思路
LCM&GCD
很显然,套两个循环这个题就TLE了;那就得简化

#include 
using namespace std;
long long  t,x,y,tex,i;
int main()
{
    while(scanf("%d",&t)!=-1)
    {
        while(t--)
        {
            int ans=0;
            cin>>x>>y;
            tex=x*y;
            for(i=x; i<=y; i++)
            {
                if(tex%i==0)//感谢灰熊大佬提供的思路,机智
                    if(tex/i>=x&&tex/i<=y&&__gcd(i,tex/i)==x)
                        ans++;
            }
            printf("%d\n",ans);
        }
        return 0;
    }
}

快速幂取模

快速幂取模

解决a^n的大数据溢出问题 还是省时间的方法,套模板就行

用处:1.算一个大数(用的比较多) 2.正经取模

C++学习之GCD&LCM&快速幂取模_第3张图片
这是一个函数 得写一个函数,a是底数,b是幂,c是模
一般都会给出模1e n+7是个素数

例题1

模板题

#include 
using namespace std;
long long quickpower(long long a,long long b,long long mod)
{
    long long ans=1;
    while(b)
    {
        if(b&1)
        {b--;ans=ans*a%mod;}//可见这个和上面的模板一模一样
        a=a*a%mod;
        b=b/2;
    }
    return ans;
}
int main()
{
    long long a,b,c;
    while(cin>>a>>b>>c)//如果c不给,一般都是1e7+7
    printf("%lld\n",quickpower(a,b,c));
    return 0;
}

例题2

库特的数学题(难)

要推题目的公式 而且数目大取模才难不爆

#include 
using namespace std;
typedef long long ll;
long long quickpower(ll a,ll b,ll mod)
{
    ll ans=1;
    while(b)
    {
        if(b&1)
        {
            b--;//这个,可有可无。但还是写上,保险起见
            ans=ans*a%mod;
        }
        a=a*a%mod;
        b=b/2;
    }
    return ans;
}
int main()
{
    ll n,sum,i,c;
    while(cin>>n)
    {
        sum=3;c=1e9+7;//公式是 2*3^n   
        printf("%lld\n",(2*quickpower(sum,n,c)%1000000007));//取一次模不够,再套一次,防止超时
    }
    return 0;
}

例题3

这个题考的是思维
异或方程的解
嫖一个陈建国大佬推导
C++学习之GCD&LCM&快速幂取模_第4张图片
还有一点 二进制的位数和2的n次方相关 二进制有三位 n就为2 想不到这点,就算知道也无招
满二进位
2的1次方 二进制是两位数
2的2次方 二进制是三位数

#include 
using namespace std;
int n,x,i,ans;
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        int p[35];
        p[0]=1;
        for(i=1; i<=30; i++)
            p[i]=2*p[i-1];//打表,算2^n次方
        for(i=1; i<=30; i++)
            if(p[i]>n)//这里直接用大数去比较,如果我比你大,那你的位次刚好比我少一。
            {
                x=i-1;//这里就是找次方,
                break;
            }
        ans=0;
        for(int i=0; i<=x; i++)//用次方数
        {
            if((1<

你可能感兴趣的:(C++,acm竞赛)