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

Problem Description
  A sequence S n 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 S n.
  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 < 2 15, (a-1) 2< b < a 2, 0 < b, n < 2 31.The input will finish with the end of file.
Output
  For each the case, output an integer S n.
 
题目大意:已知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

 

你可能感兴趣的:(ICPC)