http://acm.hdu.edu.cn/showproblem.php?pid=3221

一晚上搞出来这么一道题。。Mark。


给出这么一个程序。问funny函数调用了多少次。

我们定义数组为所求:f[1] = a,f[2] = b, f[3] = f[2]*f[3]......f[n] = f[n-1]*f[n-2]。相应的值表示也可为a^1*b^0%p。a^0*b^1%p,a^1*b^1%p,.....a^fib[n-3]*b^fib[n-2]%p。即a,b的指数从n=3以后与fib数列一样。


由于n非常大。fib[n]也想当大。

a^fib[n]%p能够利用a^fib[n]%p = a^(fib[n]%phi[p]+phi[p])%p进行降幂,条件时fib[n]>=phi[p]。求fib[n]%phi[p]能够构造矩阵。利用矩阵高速幂求fib[n]%phi[p]。


#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL long long
#define _LL __int64
#define eps 1e-12
#define PI acos(-1.0)
#define C 240
#define S 20
using namespace std;
const int maxn = 110;struct matrix
{LL mat[3][3];void init(){memset(mat,0,sizeof(mat));for(int i = 0; i < 2; i++)mat[i][i] = 1;}
} m;LL a,b,p,n,phi_p;
LL fib[10000000];//phi[p]
LL Eular(LL num)
{LL res = num;for(int i = 2; i*i <= num; i++){if(num%i == 0){res -= res/i;while(num%i == 0)num /= i;}}if(num > 1)res -= res/num;return res;
}
//矩阵相乘
matrix mul_matrix(matrix x, matrix y)
{matrix ans;memset(ans.mat,0,sizeof(ans.mat));for(int i = 0; i < 2; i++){for(int k = 0; k < 2; k++){if(x.mat[i][k] == 0) continue;for(int j = 0; j < 2; j++){ans.mat[i][j] = (ans.mat[i][j] + x.mat[i][k]*y.mat[k][j])%phi_p;}}}return ans;
}
//a^t%phi_p
LL pow_matrix(LL t)
{matrix a,b;a.mat[0][0] = a.mat[0][1] = a.mat[1][0] = 1;a.mat[1][1] = 0;b.init();while(t){if(t&1)b = mul_matrix(a,b);a = mul_matrix(a,a);t >>= 1;}return b.mat[0][0];
}
//a^t%p
LL pow(LL a, LL t)
{LL res = 1;a %= p;while(t){if(t&1)res = res*a%p;a = a*a%p;t >>= 1;}return res;
}
//a^fib[t]%p转化为a^(fib[t]%phi[p]+phi[p])%p,fib[t] >= phi[p]。
LL solve(LL a, LL t)
{fib[0] = 1;fib[1] = 1;int i;for(i = 2; i <= t; i++){fib[i] = fib[i-1] + fib[i-2];if(fib[i] >= phi_p)break;}if(i <= t) //当满足条件fib[t] >= phi[p]时,进行降幂{LL c = pow_matrix(t) + phi_p;return pow(a,c);}elsereturn pow(a,fib[t]);
}int main()
{int test;scanf("%d",&test);for(int item = 1; item <= test; item++){scanf("%lld %lld %lld %lld",&a,&b,&p,&n);printf("Case #%d: ",item);if(n == 1){printf("%lld\n",a%p);continue;}if(n == 2){printf("%lld\n",b%p);continue;}if(n == 3){printf("%lld\n",a*b%p);continue;}if(p == 1){printf("0\n");continue;}phi_p = Eular(p);LL res = solve(a,n-3)*solve(b,n-2)%p;printf("%lld\n",res);}return 0;
}

转载于:https://www.cnblogs.com/yxwkf/p/5113611.html

hdu 3221 Brute-force Algorithm(高速幂取模,矩阵高速幂求fib)相关推荐

  1. 快速幂取模——Pupu(HDU 3003)

    题目: 由题目推出计算公式: ans = (2^(n-1) + 1) % n 因为n取值很大,所以需要用到快速幂取模: int multi(int a,int b) { int ret; ret=1; ...

  2. HDU 4365 正方形格子涂色中心对称轴对称的涂法有多少种-思维-(矩阵坐标关系快速幂取模)

    题意:n*n的格子,涂色,有k种颜料,必须满足旋转任意个90度和翻转之后图片的样子不变,现在已经有m个格子涂过色了,问还有多少种涂法满足上述条件. 分析: 满足上述对称条件,那么涂色的种类问题我们可以 ...

  3. 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)

    先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...

  4. CodeForces Round #191 (327C) - Magic Five 等比数列求和的快速幂取模

    很久以前做过此类问题..就因为太久了..这题想了很久想不出..卡在推出等比的求和公式,有除法运算,无法快速幂取模... 看到了 http://blog.csdn.net/yangshuolll/art ...

  5. HDU 2276 Kiki Little Kiki 2 (位运算+矩阵快速幂)

    HDU 2276 Kiki & Little Kiki 2 (位运算+矩阵快速幂) ACM 题目地址:HDU 2276 Kiki & Little Kiki 2 题意:  一排灯,开关 ...

  6. HDU3003 Pupu,快速幂取模

    快速幂取模就是在O(logn)内求出a^n mod b的值.算法的原理是(a*b) mod c=(a mod c)*(b mod c)mod c /************************** ...

  7. c语言的幂乘积表达式,POJ 1845 Sumdiv [素数分解 快速幂取模 二分求和等比数列]

    大致题意: 求A^B的所有约数(即因子)之和,并对其取模 9901再输出. 解题基础: 1) 整数的唯一分解定理: 任意正整数都有且只有一种方式写出其素因子的乘积表达式. ,其中 为素数 2) 约数和 ...

  8. C语言快速幂取模算法小结

    资料链接:http://www.jb51.net/article/54947.htm C语言实现的快速幂取模算法,是比较常见的算法.分享给大家供大家参考之用.具体如下: 首先,所谓的快速幂,实际上是快 ...

  9. 【算法分析与设计】快速幂算法与快速幂取模算法

    文章目录 快速幂算法 算法分析 算法实现 位运算优化 BigInteger支持 快速幂取模算法 算法优点 算法推导 算法实现 BigInteger支持 本文完整代码实现(Java语言描述) 快速幂算法 ...

  10. 【快速幂取模】NOI 7833:幂的末尾

    NOI 7833:幂的末尾     点击打开链接 总时间限制: 1000ms 内存限制: 65536kB 描述 幂ab的末3位数是多少? 输入 两个正整数a,b.1 <= a <= 100 ...

最新文章

  1. 商品详细信息的代码html_电商网站的商品详情页系统架构
  2. poj2356(抽屉原理)
  3. 复旦教授发现400+安卓漏洞,最严重可使手机变砖,谷“鸽”16个月后才修复
  4. [Java基础]字节,字符打印流
  5. MySQL 性能优化 分布式
  6. mysql 磁盘组_第15期:索引设计(索引组织方式 B+ 树)
  7. C++常见编译问题问题(慢慢积累)
  8. mysql 修改root密码 修改账户登录host
  9. 0 基础 Java 自学之路(2021年最新版)
  10. python爬虫初学(3)
  11. 故障处理 软件 需求_高线轧机轴承振动在线监测与故障诊断分析
  12. 【Android安全】ActivityManager.isUserAMonkey API
  13. 简述游戏抽奖机制运用的心理学知识(上)
  14. 虎赢大数据:“企业工商数据价值挖掘”,是2020年大数据创业发展的方向之一
  15. 计算机的内存大小有何作用,电脑内存用处有多大?你可能想不到!
  16. 股票如何看股票均线-5-10-20-30-60日均线
  17. 全世界应当普及的经典文章:另辟蹊径解读《心经》
  18. Visual Studio弃Coded UI Test 给开发者建议
  19. 10+ 小故事揭秘高频「操作系统面试题」
  20. 解决桌面图标左下角蓝色问号问题

热门文章

  1. 文本文件 java_Java入门:读写文本文件
  2. c语言中++b与b++_C ++中的朋友功能
  3. c++中的向量_C ++中的向量
  4. java程序示例_Java程序中的Google搜索示例
  5. java多线程 线程安全_Java中的线程安全
  6. timezone java_如何将Java日期转换为特定的TimeZone格式
  7. scala 函数中嵌套函数_Scala函数–声明,定义,调用和嵌套函数
  8. RxJava操作符lift笔记25
  9. 云原生解决了什么问题?
  10. C++面试题,平时面试不可缺少的!