HDU 4565 So Easy!(数学+矩阵快速幂)(2013 ACM-ICPC长沙赛区全国邀请赛)
Problem Description
A sequence Sn is defined as:
![](http://acm.hdu.edu.cn/data/images/C468-1001-1.jpg)
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!
![](http://acm.hdu.edu.cn/data/images/C468-1001-1.jpg)
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.
题目大意:已知a、b、n、m,求图中Sn,向上取整后求雨。
PS:哪里简单了……至于负数比较难搞果断一开始把它弄成正数了……
代码(62MS):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <queue> 3 #include <utility> 4 #include <iostream> 5 #include <cstring> 6 using namespace std; 7 typedef long long LL; 8 9 const int N = 2; 10 11 int a, b, n, m; 12 13 #define MOD(x) ((x)%m) 14 15 struct Mat { 16 LL v[N][N]; 17 Mat operator * (const Mat &rhs) { 18 Mat ret; 19 for(int i = 0; i < N; ++i) 20 for(int j = 0; j < N; ++j) { 21 ret.v[i][j] = 0; 22 for(int k = 0; k < N; ++k) ret.v[i][j] += MOD(v[i][k] * rhs.v[k][j]); 23 ret.v[i][j] %= m; 24 } 25 return ret; 26 } 27 }; 28 29 Mat mul(Mat x, int p) { 30 Mat ans; 31 ans.v[0][0] = ans.v[1][1] = 1; 32 ans.v[0][1] = ans.v[1][0] = 0; 33 while(p > 0) { 34 if(p & 1) ans = ans * x; 35 x = x * x; 36 p >>= 1; 37 } 38 return ans; 39 } 40 41 int main() { 42 while(scanf("%d%d%d%d", &a, &b, &n, &m) != EOF) { 43 Mat tmp; 44 tmp.v[0][0] = 2 * a; 45 tmp.v[0][1] = - (a * a - b); 46 while(tmp.v[0][1] < 0) tmp.v[0][1] += m; 47 tmp.v[1][0] = 1; 48 tmp.v[1][1] = 0; 49 tmp = mul(tmp, n); 50 LL ans = MOD(2 * a * tmp.v[1][0] + 2 * tmp.v[1][1]); 51 cout<<ans<<endl; 52 } 53 }