HDU 4565 So Easy! (矩阵快速幂 + 向上取整)
So Easy!
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5228 Accepted Submission(s): 1718
Problem Description
A sequence Sn is defined as:
Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.
You, a top coder, say: So easy!
Where a, b, n, m are positive integers.┌x┐is the ceil of x. For example, ┌3.14┐=4. You are to calculate Sn.
You, a top coder, say: So easy!
Input
There are several test cases, each test case in one line contains four positive integers: a, b, n, m. Where 0< a, m < 215, (a-1)2< b < a2, 0 < b, n < 231.The input will finish with the end of file.
Output
For each the case, output an integer Sn.
Sample Input
2 3 1 2013
2 3 2 2013
2 2 1 2013
Sample Output
4
14
4
Source
这个题 与 HUD 2256 的套路 一模一样, 2256 是向下取整, 这个是向上 取整, 但是整体思路一致
HUD 2256 题解链接: http://blog.csdn.net/sizaif/article/details/77112848
构造的矩阵为 [a,b]
[1,a]
ans = 2*An An= a*X0 + b* Y0 又 X0=a,Y0=1;
所以 An = array[0][0]*a +array[0][1]
代码:
#include <iostream> #include <algorithm> #include <queue> #include <stdio.h> #include <cstring> #include <cmath> typedef long long ll; const int MAXN=2; const int N=10; using namespace std; int MOD; int a,b; struct Matrix{ ll arr[N][N]; void init() { memset(arr,0,sizeof(arr)); for(int i=0;i<MAXN;i++) arr[i][i]=1;//初始化 } void iinit() { memset(arr,0,sizeof(arr)); arr[0][0]=arr[1][1]=a; arr[0][1]=b; arr[1][0]=1; } }A; Matrix mul(Matrix X,Matrix Y)// 矩阵乘法 { Matrix ans; for(int i=0;i<MAXN;i++) for(int j=0;j<MAXN;j++){ ans.arr[i][j]=0; for(int k=0;k<MAXN;k++){ ans.arr[i][j]+=X.arr[i][k]*Y.arr[k][j]; ans.arr[i][j]%=MOD; } } return ans; } Matrix Q_pow(Matrix B,int n)// 矩阵快速幂 { Matrix ans; ans.init(); while(n) { if(n&1) ans=mul(ans,B); n>>=1; B=mul(B,B); } return ans; } int main() { int n; while(~scanf("%d %d %d %d",&a,&b,&n,&MOD)) { Matrix ans; if(n<=1) { printf("%d\n",(a+1+(int)sqrt(b))%MOD); continue; } ans.iinit(); ans=Q_pow(ans,n-1); ll res=0; // cout<<ans.arr[0][0]<<" "<<ans.arr[0][1]<<endl; res=(ans.arr[0][0]*a+ans.arr[0][1])%MOD; printf("%lld\n",(2*(res))%MOD); } return 0; }
岂曰无衣?与子同袍。王于兴师,修我戈矛。与子同仇!
岂曰无衣?与子同泽。王于兴师,修我矛戟。与子偕作!
岂曰无衣?与子同裳。王于兴师,修我甲兵。与子偕行!