您的位置:首页 > 其它

HDU 3483 A Very Simple Problem 矩阵构造

2014-11-12 22:28 459 查看

A Very Simple Problem

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)

Total Submission(s): 739 Accepted Submission(s): 378



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


/*
HDU 3483 矩阵构造

不会 转载别人的 以后再看把 
作为乘数项的矩阵不得与N有关,只能与x有关
F(n+1) = F(n) + x^(n+1) * (n+1)^x  把(n+1)^x拆分 
=F(n) + ( C(x,0)* n^x + C(x,1)* n^(x-1) + ... + C(x,x-1)*n +1)* x^(n+1)
把x^(n+1)分成x^n*x放入进去: 
=F(n) + (C(x,0)* n^x* (x^n) + C(x,1)*n^(x-1)*(x^n)+ ... +C(x,x-1)*n*(x^n)+1*(x^n))*x
=F(n) + (x*C(x,0)* n^x *(x^n) + x*C(x,1)* n^(x-1)*x^n+...)

x^(n+1)*(n+1)^x 写成了sum{g(i,n)*const(i)},const(i)与n无关,
可以乘数项矩阵的一部分),而g(i,n)可以作为最终矩阵的一部分
更重要的是,g(i,n)要和f(n)放在一起构成最终矩阵,也就是g(i,n)如何表达?

g(i+1,n) =(i+1)^x*(x^n) = (C(i,0)*i^x + C(i,1)*i^(x-1) + ..+C(i,i)*i^0) *(x^(n+1))
       = (C(i,0)*x*t0 + C(i,1)*x*t1 + ...+C(i,i)*x*ti)
tj = i^j*(x^n) = g(j,n-1) 0<=j<=i
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <vector>
 
#define N 60
#define cl(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a) 
#define ll __int64
#define pb push_back

using namespace std;
 
ll a

,c

,r
;
vector<ll>gener;
int mod,k;

void generate_cmb()
{
    int i,j;
    cl(c);
    for (i=0;i<=k;i++)
        for (j=0;j<=i;j++)
        {
            if (j==0) c[i][j]=1;
            else if (j>i-j) c[i][j]=c[i][i-j];
            else c[i][j]=c[i-1][j]+c[i-1][j-1];
        }
}

void init()
{
    int i,j;
    generate_cmb();
    cl(a);cl(r);
    for (i=0;i<=k;i++)
        for (j=0;j<=k;j++)
            a[0][i][j]=(k*c[i][j])%mod;
    for (j=0;j<=k;j++) a[0][k+1][j]=(k*c[k][j])%mod;
    a[0][k+1][k+1]=1;
    for (i=0;i<=k+1;i++) r[i]=k;        
}

void rmul(int x)
{
    int u,v,w;
    for (u=0;u<=k+1;u++)
        for (v=0;v<=k+1;v++)
        {
            for (w=0;w<=k+1;w++) 
                a[x+1][u][v]=(a[x+1][u][v]+(a[x][u][w]*a[x][w][v])%mod)%mod;
        }
}

void mul(int x)
{
    int u,v;
    ll t;
    gener.clear();
    for (u=0;u<=k+1;u++)
    {
        t=0;
        for (v=0;v<=k+1;v++) t=(t+(a[x][u][v]*r[v])%mod)%mod;
        gener.pb(t);
    }
    for (int i=0;i<=k+1;i++) r[i]=gener[i];
}

void quick(int n)
{
    int i=0;
    while (n>0)
    {
        if (n&1) mul(i);
        rmul(i);
        n>>=1;
        i++; 
    } 
}

int main()
{
    int n;
    while (ss(n)!=EOF)
    {
        ss(k);ss(mod);
        if (n<0&&k<0&&mod<0) break;
        if (n==1) 
        {
            cout<<k%mod<<endl;
            continue;
        }
        init();
        quick(n-1);
        cout<<r[k+1]<<endl;
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: