hdu 3221 Brute-force Algorithm(高速幂取模,矩阵高速幂求fib)
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);
}
else
return 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;
}
hdu 3221 Brute-force Algorithm(高速幂取模,矩阵高速幂求fib)的更多相关文章
- HDU1013,1163 ,2035九余数定理 快速幂取模
1.HDU1013求一个positive integer的digital root,即不停的求数位和,直到数位和为一位数即为数根. 一开始,以为integer嘛,指整型就行吧= =(too young ...
- CSU - 1556 Jerry's trouble(高速幂取模)
[题目链接]:click here [题目大意]:计算x1^m+x2^m+..xn^m(1<=x1<=n)( 1 <= n < 1 000 000, 1 <= m < ...
- HDU 1061 Rightmost Digit --- 快速幂取模
HDU 1061 题目大意:给定数字n(1<=n<=1,000,000,000),求n^n%10的结果 解题思路:首先n可以很大,直接累积n^n再求模肯定是不可取的, 因为会超出数据范围, ...
- hdu 1097 A hard puzzle 快速幂取模
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1097 分析:简单题,快速幂取模, 由于只要求输出最后一位,所以开始就可以直接mod10. /*A ha ...
- hdu 4506 小明系列故事——师兄帮帮忙【幂取模乱搞】
链接: http://acm.hdu.edu.cn/showproblem.php?pid=4506 http://acm.hust.edu.cn/vjudge/contest/view.action ...
- HDU 1061.Rightmost Digit-规律题 or 快速幂取模
Rightmost Digit Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- 题解报告:hdu 1061 Rightmost Digit(快速幂取模)
Problem Description Given a positive integer N, you should output the most right digit of N^N. Input ...
- HDU 4704 Sum 超大数幂取模
很容易得出答案就是2^(n-1) 但是N暴大,所以不可以直接用幂取模,因为除法操作至少O(len)了,总时间会达到O(len*log(N)) 显然爆的一塌糊涂 套用FZU1759的模板+顺手写一个大数 ...
- 数学--数论--HDU 4675 GCD of Sequence(莫比乌斯反演+卢卡斯定理求组合数+乘法逆元+快速幂取模)
先放知识点: 莫比乌斯反演 卢卡斯定理求组合数 乘法逆元 快速幂取模 GCD of Sequence Alice is playing a game with Bob. Alice shows N i ...
- UVa 11582 Colossal Fibonacci Numbers! 【大数幂取模】
题目链接:Uva 11582 [vjudge] watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fil ...
随机推荐
- Denny Zhang:一辈子做一个自由职业者
程序猿訪谈录供稿 Denny是一个旅居美国的自由职业者,这是一份让人羡慕的职业,选择这个职业意味着他已经实现某种程度上的经济自由,能够最大限度的做自己喜欢的事情,对他来说,选择自由职业作为自己终生的事 ...
- Linux内核-系统调用
Linux内核-系统调用 1.与内核通信 #系统调用在用户空间进程和硬件设备之间添加了一个中间层 作用:1.为用户空间提供了一种硬件的抽象接口 2.系统调用保证了系统的稳定和安全 3.出于每一个进程都 ...
- NYOJ10,skiing
skiing 时间限制:3000 ms | 内存限制:65535 KB 难度:5 描写叙述 Michael喜欢滑雪百这并不奇怪, 由于滑雪的确非常刺激.但是为了获得速度,滑的区域必须向下倾斜,并且 ...
- spring利用扫描方式对bean的处理(对任何版本如何获取xml配置信息的处理)
利用扫描的方式将组件注入容器,就也可以不用操作bean来实例化对象了. 下面我做一个例子 我用的spring3.2.2版本的 首先写一个spring.xml. <?xml version=&qu ...
- Java基础12 类型转换与多态
链接地址:http://www.cnblogs.com/vamei/archive/2013/04/01/2992662.html 作者:Vamei 出处:http://www.cnblogs.com ...
- OC中线程的状态相关
1.线程的状态NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil]; ...
- 幻世(OurDream)2D图形引擎使用教程8——处理操作输入(2)
声明:本教程版权归Lizcst Software Lab所有,欢迎转载,但是转载必须保留本段声明文字,并注明文章来源:http://blog.csdn.net/kflizcst 谢谢合作! 今天的教程 ...
- fullcalendar日历控件知识点集合
1.基本的语法: 首先,fullcalendar和JQUERY一样,以面向对象的方式来组织代码.当然,这里的面向对象不过指能够把整个fullcalendar理解为一个类,这个类里包含有非常多的属性.方 ...
- 编写高质量代码改善java程序的151个建议——[52-57]String !about String How to use them?
原创地址: http://www.cnblogs.com/Alandre/ (泥沙砖瓦浆木匠),须要转载的,保留下! Thanks Although the world is full of s ...
- MVC简单分页
对Car汽车表分页 实现简单分页,放在这里方便查看回顾,自定义每页几条有点问题,有待完善······ 1.新建mvc项目 2.添加linq to sql 数据库连接 3.添加CarBF类 using ...