hdu_3483A Very Simple Problem(C(m,n)+快速幂矩阵)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3483

A Very Simple Problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 945    Accepted Submission(s): 471

Problem Description

This is a very simple problem. Given three integers N, x, and M, your task is to calculate out the following value:

Input

There are several test cases. For each case, there is a line with three integers N, x, and M, where 1 ≤ N, M ≤ 2*109, and 1 ≤ x ≤ 50.
The input ends up with three negative numbers, which should not be processed as a case.

Output

For each test case, print a line with an integer indicating the result.

Sample Input

100 1 10000
3 4 1000
-1 -1 -1

Sample Output

5050
444

Source

2010 ACM-ICPC Multi-University Training Contest(5)——Host by BJTU

  1 //计算排列数(杨辉三角)
  2 //C(m,n) = C(m-1,n-1)+C(m-1,n)
  3 //快速幂
  4 /*
  5 *  [题意]
  6 *   输入n, x, m
  7 *   求(1^x)*(x^1)+(2^x)*(x^2)+(3^x)*(x^3)+...+(n^x)*(x^n)
  8 *  [解题方法]
  9 *   设f[n] = [x^n, n*(x^n), (n^2)*(x^n),..., (n^x)*(x^n)]
 10 *   则f[n][k] = (n^k)*(x^n)
 11 *   问题转化为求:( g[n] = f[1][x]+f[2][x]+...+f[n][x] )
 12 *   设C(i,j)为组合数,即i种元素取j种的方法数
 13 *   所以有:f[n+1][k] = ((n+1)^k)*(x^(n+1)) (二次多项式展开)
 14 *                     = x*( C(k,0)*(x^n)  +C(k,1)*n*(x^n)+...+C(k,k)*(n^k)*(x^n) )
 15 *                     = x*( C(k,0)*f[n][0]+C(k,1)*f[n][1]+...+C(k,k)*f[n][k] )
 16 *   所以得:
 17 *   |x*1 0................................0|        |f[n][0]|       |f[n+1][0]|
 18 *   |x*1 x*1 0............................0|        |f[n][1]|       |f[n+1][1]|
 19 *   |x*1 x*2 x*1 0........................0|    *   |f[n][2]|   =   |f[n+1][2]|
 20 *   |......................................|        |.......|       |.........|
 21 *   |x*1 x*C(k,1) x*C(k,2)...x*C(k,x) 0...0|        |f[n][k]|       |f[n+1][k]|
 22 *   |......................................|        |.......|       |.........|
 23 *   |x*1 x*C(x,1) x*C(x,2).......x*C(x,x) 0|        |f[n][x]|       |f[n+1][x]|
 24 *   |0................................0 1 1|        |g[n-1] |       | g[ n ]  |
 25 */
 26 #include<cstdio>
 27 #include<cstring>
 28 #include<cmath>
 29 #include<algorithm>
 30 using namespace std;
 31 #define ll long long
 32 const ll maxn = 55;
 33 ll c[maxn][maxn];
 34 ll n, mod, x, m;
 35 struct Mat{
 36     ll f[maxn][maxn];
 37 };
 38 void init()
 39 {
 40     ll i,j,k;
 41     c[0][0] = c[1][0] = c[1][1] = 1;
 42     for(i = 2; i < maxn; i++){
 43         c[i][0] = c[i][i] = 1;
 44         for(j = 1; j < i; j++){
 45             c[i][j] = c[i-1][j]+c[i-1][j-1];
 46         }
 47     }
 48 }
 49 Mat operator *(Mat a, Mat b)
 50 {
 51     ll i, j, k;
 52     Mat c;
 53     memset(c.f,0,sizeof(c.f));
 54     for(k = 0; k < m; k++){
 55         for(i = 0; i < m; i++){
 56             for(j = 0; j < m; j++){
 57                 if(!b.f[k][j]) continue;
 58                 c.f[i][j] = (c.f[i][j]+(a.f[i][k]*b.f[k][j])%mod)%mod;
 59             }
 60         }
 61     }
 62     return c;
 63 }
 64 Mat multi(Mat a,ll b)
 65 {
 66     Mat s;
 67     memset(s.f,0,sizeof(s.f));
 68     for(int i = 0; i < m; i++){
 69         s.f[i][i] = 1;
 70     }
 71     while(b){
 72         if(b&1) s = s*a;
 73         a = a*a;
 74         b>>=1;
 75     }
 76     return s;
 77 }
 78 int main()
 79 {
 80     init();
 81     while(~scanf("%lld%lld%lld",&n,&x,&mod))
 82     {
 83         if(n<0&&x<0&&mod<0) break;
 84         Mat e;
 85         ll i, j;
 86         ll ans = 0;
 87         memset(e.f,0,sizeof(e.f));
 88         for(i = 0; i <= x; i++){
 89             for(j = i; j <= x; j++){
 90                 e.f[j][i] = c[x-i][j-i]*x%mod;
 91             }
 92         }
 93         e.f[0][x+1] = e.f[x+1][x+1] = 1;
 94         m = x+2;
 95         e = multi(e,n);
 96         for(i = 0; i < m-1; i++) ans = (ans+x*e.f[i][m-1])%mod;
 97         printf("%lld\n",(ans+mod)%mod);
 98     }
 99     return 0;
100 }
时间: 2024-10-18 19:35:00

hdu_3483A Very Simple Problem(C(m,n)+快速幂矩阵)的相关文章

Number Sequence(快速幂矩阵)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1005 Number Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 131753    Accepted Submission(s): 31988 Problem Description A number sequence

hdu 4965 矩阵快速幂 矩阵相乘性质

Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 170    Accepted Submission(s): 99 Problem Description One day, Alice and Bob felt bored again, Bob knows Alice is a gir

hdu_2604Queuing(快速幂矩阵)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2604 Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4428    Accepted Submission(s): 1961 Problem Description Queues and Priority Queues a

[POJ 3150] Cellular Automaton (矩阵快速幂 + 矩阵乘法优化)

Cellular Automaton Time Limit: 12000MS   Memory Limit: 65536K Total Submissions: 3048   Accepted: 1227 Case Time Limit: 2000MS Description A cellular automaton is a collection of cells on a grid of specified shape that evolves through a number of dis

HDU 3306 Another kind of Fibonacci(快速幂矩阵)

题目链接 构造矩阵 看的题解,剩下的就是模板了,好久没写过了,注意取余. #include <cstring> #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define MOD 10007 #defin

菲波那契数列的快速幂矩阵求法

时间:2014.05.15 地点:基地二楼 ----------------------------------------------------------------------- 一.背景 著名的斐波那契数列为一个这样的序列:0 1 1 2 3 5 8 13 21 34......简单的递推公式如下: F(0)=0,F(1)=1,当n>=1时,F(n)=F(n-1)+F(n-2) 显然,我们用直接的按公式递归的算法去计算该数列的第n项效率并不高,因为这样每次递归调用我们只是将规规模缩小了

HDU 4686 Arc of Dream(快速幂矩阵)

题目链接 再水一发,构造啊,初始化啊...wa很多次啊.. #include <cstring> #include <cstdio> #include <string> #include <iostream> #include <algorithm> #include <vector> #include <queue> using namespace std; #define MOD 1000000007 #define

斐波那契优化 快速幂+矩阵乘法

题目:你能求得第n个斐波那契数吗?0<n<maxlongint 由于结果太大,输出的结果mod32768 思路:一般的求斐波那契数列的方法有递归,动归,或者用滚动优化,但是空间复杂或者时间复杂度都太高了,现在有一种用矩阵加快速幂的优化算法,可以让时间复杂度维持在logn. 具体的 初始化一个2×2的矩阵,初始值为{1,0,0,1} 则分别代表{a2,a1,a1,a0},把此矩阵平方后得到{2,1,1,0}分别代表{a3,a2,a2,a1}如此下去,便可以得到规律,其实这个算法主要就是优化在快速

HDU 4965 Fast Matrix Caculation ( 矩阵乘法 + 矩阵快速幂 + 矩阵乘法的结合律 )

HDU 4965 Fast Matrix Calculation ( 矩阵乘法 + 矩阵快速幂 + 矩阵乘法的结合律 ) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define MAX_SIZE 1001 #define CLR( a, b ) memset( a, b, sizeof(a) ) #define MOD 6 typedef long lo