• 【HDOJ】3221 Brute-force Algorithm


    归来吧很好推导。T(n) = a^f(n-1)*b^f(n)%p。
    主要难点在于求mod和fibo。引用如下公式
    A^B%C = A^(B%phi(C) + phi(C))%C, 满足B>=phi(C)。

      1 /*  */
      2 #include <iostream>
      3 #include <string>
      4 #include <map>
      5 #include <queue>
      6 #include <set>
      7 #include <stack>
      8 #include <vector>
      9 #include <deque>
     10 #include <algorithm>
     11 #include <cstdio>
     12 #include <cmath>
     13 #include <ctime>
     14 #include <cstring>
     15 #include <climits>
     16 #include <cctype>
     17 #include <cassert>
     18 using namespace std;
     19 
     20 #define rep(i,a,n)     for (int i=a;i<n;i++)
     21 #define per(i,a,n)     for (int i=n-1;i>=a;i--)
     22 #define pb             push_back
     23 #define mp             make_pair
     24 #define all(x)         (x).begin(),(x).end()
     25 #define SZ(x)         ((int)(x).size())
     26 #define lson        l, mid, rt<<1
     27 #define rson        mid+1, r, rt<<1|1
     28 
     29 const int maxn = 1000001;
     30 __int64 a, b, p, n;
     31 __int64 fibo[maxn];
     32 __int64 phi;
     33 
     34 typedef struct {
     35     __int64 m[2][2];
     36 } mat_t;
     37 
     38 mat_t res;
     39 
     40 mat_t matMult(mat_t a, mat_t &b) {
     41     mat_t c;
     42     
     43     memset(c.m, 0, sizeof(c.m));
     44     rep(i, 0, 2) {
     45         rep(j, 0, 2) {
     46             rep(k, 0, 2) {
     47                 c.m[i][j] += a.m[i][k] * b.m[k][j];
     48                 if (c.m[i][j] > phi) {
     49                     c.m[i][j] = c.m[i][j]%phi+phi;
     50                 }
     51             }
     52         }
     53     }
     54     return c;
     55 }
     56 
     57 __int64 euler(__int64 x) {
     58     __int64 ret = x, i;
     59     
     60     for (i=2; i*i<=x; ++i) {
     61         if (x%i == 0) {
     62             ret = ret / i * (i-1);
     63             while (x%i == 0)
     64                 x /= i;
     65         }
     66     }
     67     if (x > 1)
     68         ret = ret / x * (x-1);
     69     return ret;
     70 }
     71 
     72 __int64 myPow(__int64 base, __int64 n) {
     73     __int64 ret = 1;
     74     
     75     while (n) {
     76         if (n & 1)
     77             ret = ret * base %p;
     78         base = base * base %p;
     79         n >>= 1;
     80     }
     81     return ret;
     82 }
     83 
     84 void matFibo(__int64 n) {
     85     mat_t base;
     86     
     87     res.m[0][0] = base.m[0][0] = 0;
     88     res.m[0][1] = res.m[1][0] = res.m[1][1] =
     89     base.m[0][1] = base.m[1][0] = base.m[1][1] = 1;
     90     
     91     while (n) {
     92         if (n & 1)
     93             res = matMult(base, res);
     94         base = matMult(base, base);
     95         n >>= 1;
     96     }
     97 }
     98 
     99 void getFibo(__int64 &an, __int64 &bn) {
    100     int i;
    101     
    102     fibo[1] = 0;
    103     fibo[2] = 1;
    104     for (i=3; i<=n; ++i) {
    105         fibo[i] = fibo[i-1] + fibo[i-2];
    106         if (fibo[i] > phi)
    107             break;
    108     }
    109     if (i > n) {
    110         an = fibo[n-1];
    111         bn = fibo[n];
    112         return ;
    113     }
    114     matFibo(n-3);
    115     an = res.m[1][0];
    116     bn = res.m[1][1];
    117 }
    118 
    119 int main() {
    120     int i, j, k;
    121     int t;
    122     __int64 an, bn, ans;
    123     
    124     #ifndef ONLINE_JUDGE
    125         freopen("data.in", "r", stdin);
    126         freopen("data.out", "w", stdout);
    127     #endif
    128     
    129     scanf("%d", &t);
    130     rep(tt, 1, t+1) {
    131         scanf("%I64d %I64d %I64d %I64d", &a, &b, &p, &n);
    132         printf("Case #%d: ", tt);
    133         if (a==0 || b==0 || p==1) {
    134             printf("0
    ");
    135         } else if (n == 1) {
    136             printf("%I64d
    ", a%p);
    137         } else if (n == 2) {
    138             printf("%I64d
    ", b%p);
    139         } else {
    140             phi = euler(p);
    141             getFibo(an, bn);
    142             ans = myPow(a, an)*myPow(b, bn)%p;
    143             printf("%I64d
    ", ans);
    144         }
    145     }
    146     
    147     #ifndef ONLINE_JUDGE
    148         printf("time = %d.
    ", (int)clock());
    149     #endif
    150     
    151     return 0;
    152 }
  • 相关阅读:
    關於GoogleUpdate.exe
    [ZT]网站优化之页面优化重新整理
    [ZT]企业建站常用中英文对照表
    "因為整合式windows驗證沒有啟用"解決方式
    模态与非模态的弹出窗口
    [ZT]ASP.Net常用正则表达式
    【ZT】基于.Net的SAP Portal开发
    .Net Quick start for the OpenFlashChart control
    微软将发布10款假补丁 测试Windows 7升级机制
    【ZT】Oracle初学者必知的100个问题
  • 原文地址:https://www.cnblogs.com/bombe1013/p/4460451.html
Copyright © 2020-2023  润新知