zoukankan      html  css  js  c++  java
  • 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
     
      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
    ",(ans+mod)%mod);
     98     }
     99     return 0;
    100 }
  • 相关阅读:
    智能电视可以安装软件就可以摆脱很多限制,而且可以和PC共享影音资源这个很靠谱。
    【转载】福昕PDF电子文档处理套件 企业版 注册码 注册方法
    OS X系列文章 AirPlay+Apple TV影音方案研究[转]
    SHARP 316L打印机64位驱动问题
    我和电脑的二三事
    北信源DeviceRegister.exe的卸载方法 【转】
    上篇随笔的补充。
    ApplicationCommands用于表示应用程序程序员经常遇到的常见命令,类似于ctrl+c
    WPF中类似使用tab键功能,可以向上向下定位
    c#通过datatable导出excel和word
  • 原文地址:https://www.cnblogs.com/shanyr/p/5668984.html
Copyright © 2011-2022 走看看