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

GCD&LCM&快速幂取模

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

GCD&LCM

1.1 GCD

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

1.2 LCM

取最小公倍数 这个没有函数 但能通过gcd函数求
如下
在这里插入图片描述
写成这样是防止数据溢出 ( a * b )

1.3 素因子法

这个方法能减少时间复杂度
在这里插入图片描述
上题

GCD&LCM例题1

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

#include <bits/stdc++.h>
using namespace std;
int n;
long long a[12],ans;
int main()
{
    while(scanf("%d",&n)!=-1)
    {
        for(int i=0; i<n; i++)
            cin>>a[i];
        ans=a[0];
        for(int i=1; i<n; i++)
            ans =__gcd(ans,a[i]);//直接套函数,它能记下最大的
        printf("%lld\n",ans);
    }
    return 0;
}

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

GCD&LCM例题2

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

#include <bits/stdc++.h>
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.正经取模

在这里插入图片描述
这是一个函数 得写一个函数,a是底数,b是幂,c是模
一般都会给出模1e n+7是个素数

例题1

模板题

#include <bits/stdc++.h>
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 <bits/stdc++.h>
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

这个题考的是思维
异或方程的解
嫖一个陈建国大佬推导

还有一点 二进制的位数和2的n次方相关 二进制有三位 n就为2 想不到这点,就算知道也无招
满二进位
2的1次方 二进制是两位数
2的2次方 二进制是三位数

#include <bits/stdc++.h>
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<<i)&n)//这已经找到了答案,但是别把自己算进去
                ans++;
        }//上面这一堆可有可无,直接ans=x就行了
        printf("%d\n",p[ans]);
    }
    return 0;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tancy.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值