Jackiesteed

www.github.com/jackiesteed

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

关键是使用这个公式来消掉循环,证明见:AekdyCoin' Blog.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <vector>
#include <list>
#include <deque>
#include <climits>
#include <algorithm>
#include <queue>
#include <functional>

using namespace std;


#if 0
#define d64 "%lld"
#else
#define d64 "%I64d"
#endif
#define mp make_pair
typedef long long LL;
typedef pair<intint> pii;
typedef pair<LL, LL> pll;
const double EPS = 1e-10;

int phi[1100000];
LL n, P, a, b;
void allPhi()
{
    phi[1] = 1;
    int n = 1000000;
    for(int i = 2; i <= n; i++)
    {
        if(!phi[i])
        {
            for(int j = i; j <= n; j += i)
            {
                if(!phi[j])
                phi[j] = j;
                phi[j] = phi[j] / i * (i - 1);
            }
        }
    }
}

void print(int a, LL b)
{
    printf("Case #%d: "d64"\n", a, b);
}
LL powMod(LL a, LL b, LL p)
{
    LL ans = 1;
    LL tmp = a % p;
    while(b)
    {
        if(b & 1)
        ans = ans * tmp % p;
        tmp = tmp * tmp % p;
        b >>= 1;
    }
    return ans;
}

void mul(LL A[2][2], LL B[2][2], LL C[2][2], LL p)
{
    for(int i = 0; i < 2; i++)
    {
        for(int j = 0; j < 2; j++)
        {
            A[i][j] = 0;
            for(int k = 0; k < 2; k++)
            {
                A[i][j] = (B[i][k] * C[k][j] + A[i][j]) % p;
            }
        }
    }
}
LL work()
{
    LL B[2][2] = {1110};
    LL C[2][2] = {1001};
    LL D[2][2];
    LL c = n - 3;
    while(c)
    {
        if(c & 1)
        {
            memcpy(D, C, sizeof(C));
            mul(C, D, B, phi[P]);
        }
        c >>= 1;
        memcpy(D, B, sizeof(B));
        mul(B, D, D, phi[P]);
    }
    LL x = (C[0][0] + C[0][1]) % phi[P];
    LL y = (C[1][0] + C[1][1]) % phi[P];
    x += phi[P], y += phi[P];

    LL ans = 1;
    ans = powMod(a, y, P) * powMod(b, x, P) % P;
    return ans;

}
int main()
{

//    freopen("input.txt", "r", stdin);

    int T;
    scanf("%d", &T);
    allPhi();

    for(int loop = 1; loop <= T; loop++)
    {
        scanf(d64 d64 d64 d64, &a, &b, &P, &n);
        if(n <=50)
        {
            if(n == 1)
            {
                print(loop, a % P);
            }
            else if(n == 2)
            {
                print(loop, b % P);
            }
            else
            {
                LL x = 1, y = 1;
                for(int i = 0; i < n - 3; i++)
                {
                    LL tmp = y;
                    y += x;
                    x = tmp;
                }
                LL ans = powMod(a, x, P) * powMod(b, y, P) % P;
                print(loop, ans);
            }
        }
        else
        {
            LL ans = work();
            print(loop, ans);
        }

    }

    return 0;
}

* This source code was highlighted by YcdoiT. ( style: Wombat )

posted on 2011-08-21 23:51  Jackiesteed  阅读(113)  评论(0编辑  收藏  举报