HDU 4565 So Easy!(数学+矩阵快速幂)(2013 ACM-ICPC长沙赛区全国邀请赛)

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! 
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):
 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 }
View Code

 

posted @ 2013-08-22 00:05  Oyking  阅读(419)  评论(0编辑  收藏  举报