数论——同余和费马小定理

同余:如果对于a和b,有a-b求余m等于零,则我们说a和b同余,记为a≡b(mod m)

其实我们也可以通俗易懂的总结一下,就是a mod m == b mod m

互质:gcd(a,b) == 1,我们就说两个数是互质的

费马小定理:对于a和p两个互质的数,存在等式a^(p-1)≡1(mod p)

我们举个经典的例子吧

对于2^100 mod 13 我可以看到,这里13和2是互质的,我们要用费马小定理的话应该怎么办?

是不是要构造出13-1啊!所以有 2^100≡(2^((12*8)+4))(mod 13),到了这一步,我们就可以用费马小定理了

对于2^12 是不是有2^12≡1mod13,所以我们去替换就行了

说的更明白点就是,2^100 和 2^((12*8)+4)) 取摸 13 的值相等,也就是和 (2^(12*8)mod13 * 2^4mod13)mod13相等,也就是和((1mod13)^8*2^4mod13)mod13相等,说到这里,大家就应该明白了吧,我这辈子应该也忘不了了吧

下面给一个经典题目吧

这个题目重在条件转换,这是数论题目的常规操作

我们首先需要理解S(k) be the number of (x1,x2,......,xk),这句话的意思是S(k)代表k个数能相加等于N的序列数目

然后还有一个问题是,例如N等于3,k = 2时,1+2和2+1是不是一个序列,这个问题模棱两可,但是数论问题就是要找规律,我们认定这是两个序列的话,容易得出来,S(1) + .... +S(N)等于2^(n-1),这样就可以用到费马小定理了!

具体见下面的AC代码 

Input

2

Output

2
#include<iostream>
#include<cstdio>
#include<string>
using namespace std;
typedef long long ll;
string n;
int main()
{
    while(cin>>n)
    {
        ll mod = 1000000006;
        ll sum = 0;
        ll power = 10;
        ll k = n.size()-1;
        while(n[k] == '0')
        {
            k--;
        }
        n[k] = n[k] - 1;
        for(ll i = n.size()-1; i > k; i--)
        {
            n[i] = '9';
        }
        for(ll i = 0; i < n.size(); i++)
        {
            sum = sum * power + (n[i]-'0');
            if(sum >= mod)
            {
                sum %= mod;
            }
        }
        ll a = 2;
        ll result = 1;
        ll mod1 = 1000000007;
        while(sum)
        {
            if(sum % 2 == 1) result = (result*a)%mod1;
            a = (a*a)%mod1;
            sum/=2;
        }
        cout<<result<<endl;
    }
    return 0;
}

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值