HDU 5667 Sequence
2016-04-25 11:16
288 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5667
题意:给一个递推式,求第n项。
思路:
Fn全部是以a为底数的幂,所以我们先忽略底数,将第n项的指数算出来,再计算fn。
设指数为pi,p1 = 0,p2 = b,pn = b + c * p(n-1) + p(n-2)
由于n非常大,所以我们需要用矩阵+快速幂来计算。
根据转移式我们可以构造出一个矩阵乘法,乘一个矩阵就转移一项。
还有一个问题是如果指数很大,也需要取模,假设现在需要算a^y % p的结果,我们需要对y进行取模来保存结果,如果存在a^x
% p = 1,我们就可以将y对x取模,也就是a^y
= a^x *a^x*....a^(y % x) = 1*1*...*a^(y % x)。因为P为质数,所以此时的x为p-1(费马小定理)。
{ pi-2 , pi-1 , b }
×
{ 0 1 0 } => { pi-1 , pi , b }
{ 1 c 0 }
{ 0 1 1 }
题意:给一个递推式,求第n项。
思路:
Fn全部是以a为底数的幂,所以我们先忽略底数,将第n项的指数算出来,再计算fn。
设指数为pi,p1 = 0,p2 = b,pn = b + c * p(n-1) + p(n-2)
由于n非常大,所以我们需要用矩阵+快速幂来计算。
根据转移式我们可以构造出一个矩阵乘法,乘一个矩阵就转移一项。
还有一个问题是如果指数很大,也需要取模,假设现在需要算a^y % p的结果,我们需要对y进行取模来保存结果,如果存在a^x
% p = 1,我们就可以将y对x取模,也就是a^y
= a^x *a^x*....a^(y % x) = 1*1*...*a^(y % x)。因为P为质数,所以此时的x为p-1(费马小定理)。
{ pi-2 , pi-1 , b }
×
{ 0 1 0 } => { pi-1 , pi , b }
{ 1 c 0 }
{ 0 1 1 }
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <cstdlib> #include <iostream> #include <algorithm> #include <stack> #include <map> #include <set> #include <vector> #include <sstream> #include <queue> #include <utility> using namespace std; #define rep(i,j,k) for (int i=j;i<=k;i++) #define Rrep(i,j,k) for (int i=j;i>=k;i--) #define Clean(x,y) memset(x,y,sizeof(x)) #define LL long long #define ULL unsigned long long #define inf 0x7fffffff #define mod %100000007 int T; int a,b,c; int p; LL n; struct martix { LL a[3][3]; }; martix multi( martix x, martix y ,int p) { martix temp; rep(i,0,2) rep(j,0,2) { temp.a[i][j] = 0; rep(k,0,2) { temp.a[i][j]+=x.a[i][k]*y.a[k][j]; temp.a[i][j]%=p; } } return temp; } int pow_mod(int a , int b , int m ) //快速幂取模 { a%=m; LL ans = 1; LL temp = a; while(b) { if ( b & 1 ) ans = ( ans * temp ) % m; temp = ( temp * temp ) % m; b>>=1; } return (int)ans; } int main() { cin>>T; while(T--) { scanf("%I64d %d %d %d %d",&n,&a,&b,&c,&p); if ( n <=2 ) { if ( n == 1 ) puts("1"); else printf("%d\n",pow_mod(a,b,p)); continue; } if ( a % p == 0 ) { puts("0"); continue; } //需要转移n-2次 n-=2; // 矩阵快速幂 x存答案,一开始为单位矩阵 martix x; //temp记矩阵的2^i幂 martix temp; rep(i,0,2) rep(j,0,2) x.a[i][j] = (i==j)?1:0; temp.a[0][0] = temp.a[0][2] = temp.a[1][2] = temp.a[2][0] = 0; temp.a[0][1] = temp.a[1][0] = temp.a[2][1] = temp.a[2][2] = 1; temp.a[1][1] = c%(p-1); while( n ) { if ( n & 1 ) x = multi( temp , x , (p-1)); temp = multi( temp,temp,(p-1) ); n>>=1; } LL t[3] = {0,b,b};//初始矩阵{ p1 p2 b } LL ans[3];//记录最终的矩阵{ pn-1 pn b } rep(i,0,2) { ans[i] = 0; rep(j,0,2) ans[i] = ( ans[i] + t[j]*x.a[j][i] ) % (p-1); } printf("%d\n",pow_mod( a , ans[1], p )); } return 0; }
相关文章推荐
- iOS中Xcode使用UIScrollView+AutoLayout轻松实现滚动布局
- iOS 通过UIDevice 获取系统相关属性
- 个性化 UIAlertController
- 【CodeForces 618B 】Guess the Permutation(水题)
- WM_CLOSE,WM_QUIT,WM_DESTROY消息的区别
- 解决StoryBoard上cell上定义的view的背景点击后不显示的问题(其中用uiview 当作线的时候最多遇到,会不显示线 而出现不流畅问题)
- UICollectionView 基础篇
- LeetCode 64/62/63. Minimum Path Sum/ Unique Paths i, ii
- UILabel文字重叠
- Quick Sort
- 我写了一个java实体类,implements了Serializable接口,然后我如何让serialversionUID自动生成
- hdu 3836 Equivalent Sets //tarjan+缩点
- 2016.04.25,英语,《Vocabulary Builder》Unit 18
- Mavlink地面站编写之五-Mission Planner中ProgressReporterDialogue和读串口线程serialreaderthread的分析
- JAVA--建造者模式(Builder)--设计模式四
- Warning: The Copy Bundle Resources build phase contains this target's Info.plist file 'x/info.plist'
- 从为什么String=String谈到StringBuilder和StringBuffer
- pip自动生成requirements.txt依赖关系清单
- UITableView取消多余的表格线条
- 关于UIScrollView不能响应UITouch事件的解决办法