zoukankan      html  css  js  c++  java
  • HDU-3221

    Brute-force Algorithm

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 2560    Accepted Submission(s): 657


    Problem Description
    Professor Brute is not good at algorithm design. Once he was asked to solve a path finding problem. He worked on it for several days and finally came up with the following algorithm:

    Any fool but Brute knows that the function “funny” will be called too many times. Brute wants to investigate the number of times the function will be called, but he is too lazy to do it.

    Now your task is to calculate how many times the function “funny” will be called, for the given a, b and n. Because the answer may be too large, you should output the answer module by P.
     
    Input
    There are multiple test cases. The first line of the input contains an integer T, meaning the number of the test cases.

    For each test cases, there are four integers a, b, P and n in a single line.
    You can assume that 1≤n≤1000000000, 1≤P≤1000000, 0≤a, b<1000000.
     
    Output
    For each test case, output the answer with case number in a single line.
     
    Sample Input

    3
    3 4 10 3
    4 5 13 5
    3 2 19 100

     
    Sample Output
    Case #1: 2
    Case #2: 11
    Case #3: 12
     
    Source
     
    /**
        题意:根据题意可以知道求 f(n) = f(n-1)*f(n-2)的值
            f(1) = a
            f(2) = b;
            f(3) = a*b;
            f(4) = a*b^2
            f(5) = a^2*b^3
            ......
            可以得知 a,b 的指数是斐波纳锲数列
        做法:欧拉 + 矩阵 + 蒙哥马利幂模算法  
          ps:没有搞清楚一点 在求矩阵的n-3次幂可以过 可是n-2次幂 不能过 *
    */ #include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; #define SIZE 2 #define clr( a, b ) memset( a, b, sizeof(a) ) long long MOD; struct Mat { long long mat[ SIZE ][ SIZE ]; int n; Mat(int _n) { n = _n; clr(mat, 0); } void init() { for(int i = 0; i < n; ++i) for(int j = 0; j < n; ++j) { mat[i][j] = (i == j); } } Mat operator * (const Mat& b) const { Mat c(b.n); for(int k = 0; k < n; ++k) for(int i = 0; i < n; ++i) { if(mat[i][k]) for(int j = 0; j < n; ++j) { c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j]) % MOD; } } return c; } }; Mat fast_mod(Mat a, int b) { Mat res(a.n); res.init(); while(b) { if(b & 1) { res = res * a; } a = a * a; b >>= 1; } return res; } long long eular(long long n) { long long ans = n; for(int i = 2; i * i <= n; i++) { if(n % i == 0) { ans -= ans / i; while(n % i == 0) { n /= i; } } } if(n > 1) { ans -= ans / n; } return ans; } long long modPow(long long s, long long index, long long mod) { long long ans = 1; s %= mod; while(index >= 1) { if((index & 1) == 1) { //奇数 ans = (ans * s) % mod; } index >>= 1; s = s * s % mod; } return ans; } int main() { int T; int Case = 1; scanf("%d", &T); while(T--) { long long x, y, n, res, p; cin >> x >> y >> p >> n; printf("Case #%d: ", Case++); if(p == 0 || p == 1) { printf("0 "); continue; } if(n == 1) { cout << x % p << endl; continue; } else if(n == 2) { cout << y % p << endl; continue; } MOD = eular(p); Mat C(2); C.mat[0][0] = 0; C.mat[0][1] = 1; C.mat[1][0] = 1; C.mat[1][1] = 1; C = fast_mod(C, n - 3); long long aa = C.mat[0][0] + C.mat[0][1]; long long bb = C.mat[1][1] + C.mat[1][0]; res = ((modPow(x , aa, p) * modPow(y , bb, p)) % p + p) % p; cout << res << endl; } return 0; }
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    #define SIZE 2
    #define clr( a, b ) memset( a, b, sizeof(a) )
    long long MOD;
    struct Mat
    {
        long long mat[ SIZE ][ SIZE ];
        int n;
        Mat(int _n) {
            n = _n;
            clr(mat, 0);
        }
        void init() {
            for(int i = 0; i < n; ++i)
                for(int j = 0; j < n; ++j) {
                    mat[i][j] = (i == j);
                }
        }
        Mat operator * (const Mat& b) const {
            Mat c(b.n);
            for(int k = 0; k < n; ++k)
                for(int i = 0; i < n; ++i) {
                    if(mat[i][k])
                        for(int j = 0; j < n; ++j) {
                            c.mat[i][j] = (c.mat[i][j] + mat[i][k] * b.mat[k][j]) % MOD;
                        }
                }
            return c;
        }
    };
    
    Mat fast_mod(Mat a, int b)
    {
        Mat res(a.n);
        res.init();
        while(b)
        {
            if(b & 1) {
                res = res * a;
            }
            a = a * a;
            b >>= 1;
        }
        return res;
    }
    
    long long eular(long long n)
    {
        long long ans = n;
        for(int i = 2; i * i <= n; i++)
        {
            if(n % i == 0)
            {
                ans -= ans / i;
                while(n % i == 0) {
                    n /= i;
                }
            }
        }
        if(n > 1) {
            ans -= ans / n;
        }
        return ans;
    }
    long long modPow(long long s, long long index, long long mod)
    {
        long long ans = 1;
        s %= mod;
        while(index >= 1)
        {
            if((index & 1) == 1) { //奇数
                ans = (ans * s) % mod;
            }
            index >>= 1;
            s = s * s % mod;
        }
        return ans;
    }
    int main()
    {
        int T;
        int Case = 1;
        scanf("%d", &T);
        while(T--)
        {
            long long x, y, n, res, p;
            cin >> x >> y >> p >> n;
            printf("Case #%d: ", Case++);
            if(p == 0 || p == 1) {
                printf("0
    ");
                continue;
            }
            if(n == 1)
            {
                cout << x % p << endl;
                continue;
            }
            else if(n == 2)
            {
                cout << y % p << endl;
                continue;
            }
            MOD = eular(p);
            Mat C(2);
            C.mat[0][0] = 1;
            C.mat[0][1] = 1;
            C.mat[1][0] = 1;
            C.mat[1][1] = 0;
            C = fast_mod(C, n - 3);
            long long aa = C.mat[1][0] + C.mat[1][1];
            long long  bb = C.mat[0][0] + C.mat[0][1];
            res = ((modPow(x , aa, p) * modPow(y , bb, p)) % p + p) % p;
            cout << res << endl;
        }
        return 0;
    }
  • 相关阅读:
    欧拉计划之题目7:找出第10001个质数
    DShow实现一个avi视频的播放(含有个人解释和注释)
    DirectX 9 SDK安装后在vs2010里编译BaseClasses出错问题解决方法
    C#内存占用大量资源的解决办法
    C#读写ini文件操作
    【Java】编程技术经典书籍列表
    【数据库_Mysql】查询当前年份的sql
    【数据库_Mysql】MySQL动态语句 if set choose where foreach trim
    【JavaScript】20款漂亮的css字体
    【数据库_Mysql】<foreach>标签在Mysql中的使用
  • 原文地址:https://www.cnblogs.com/chenyang920/p/4855218.html
Copyright © 2011-2022 走看看