1. 程式人生 > >“玲瓏杯”ACM比賽 Round #18 B -- 數論你還會快速冪【規律】

“玲瓏杯”ACM比賽 Round #18 B -- 數論你還會快速冪【規律】

B -- 數論你還會快速冪

Time Limit:5s Memory Limit:256MByte

Submissions:405Solved:85

DESCRIPTION

今天HHHH在學數論,他看到一個很優美的式子:

ni=1ikmodp∑i=1nik mod p

一向熱衷於抱隊友大腿的HHHH便問隊友ZZZZ怎麼做

ZZZZ:"n,kn,k多大?"

HHHH:"105,105105,105"

ZZZZ:"快速冪嘛"

HHHH:"109,105109,105"

ZZZZ:"拉格朗日插值嘛"

HHHH:"1018,10181018,1018"

隊友:"讓我想想.."

INPUT 第一行是一個整數T
(1T1000)
T(1≤T≤1000)
,表示有TT組資料對於每組資料輸入一行3個整數n,k,p(1n1018,0k1018,1p1018,0np100)n,k,p(1≤n≤1018,0≤k≤1018,1≤p≤1018,0≤n−p≤100)且模數 pp 是質數, OUTPUT 對於每組資料輸出題目中的表示式的值 SAMPLE INPUT 2 5 2 3 7 2 3 SAMPLE OUTPUT 1 2 HINT 對於第一組樣例我們有 12+22+32+42+52=1(mod3)12+22+32+42+52=1(mod3)對於第二組樣例我們有 12+22+32+42+
52+62+72=2(mod3)
12+22+32+42+52+62+72=2(mod3)

通過打表能夠找到規律:

①首先我們知道,i^k%p和(i+p)^k%p的價值是一樣的。

那麼肯定以長度p為迴圈節,是有迴圈內容的。

②當k不是p-1的倍數的時候,我們發現,每一段長度為p的內容加和%p都是0.

②當k是p-1的倍數的時候,我們發現,每一段長度為p的內容加和都是p-1.

那麼按照這個規律寫一下即可。

注意k==0的時候。

Ac程式碼:

#include<stdio.h>
#include<string.h>
using namespace std;
#define ll long long int
ll n,p,k;
ll kuaisucheng(ll a,ll b)
{
    ll ans=0;
    while(b)
    {
        if(b&1)
        {
            ans=(ans+a);
            if(ans>=p)ans-=p;
        }
        a=(a+a);
        if(a>=p)a-=p;
        b/=2;
    }
    return ans;
}
ll kuaisumi(ll a,ll b)
{
        a%=p;
        ll ans=1;
        while(b)
        {
            if(b&1)
            {
                ans=kuaisucheng(ans,a);
            }
            a=kuaisucheng(a,a);
            b/=2;
        }
        return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%lld%lld%lld",&n,&k,&p);
        if(k==0)
        {
            printf("%lld\n",n%p);
            continue;
        }
        ll sum=0;
        if(k%(p-1)==0)
        {
            sum+=kuaisucheng((ll)n/p,p-1);
            sum%=p;
        }
        n%=p;
        for(ll i=1;i<=n;i++)
        {
            sum+=kuaisumi(i,k);
            sum%=p;
        }
        printf("%lld\n",sum%p);
    }
}