數論——同餘和費馬小定理

同餘:如果對於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;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章