A Very Simple Problem

A Very Simple Problem

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 88 Accepted Submission(s): 55
 
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
 
Recommend
zhengfeng
 
/*
题意:给你n,x,m,让你求1^x*x^1+2^x*x^2+...+n^x*x^n;

初步思路:刚开始一点思路也没有,看了题解才发现妙处。

#补充:设F[n]=x^n,n*(x^n),(n^2)*(x^n),...,(n^x)*(x^n);
       得到:
         F[n][k]=(n^k)*(x^n);
       则要求的结果为:
         G[n]=F[1][k]+F[2][k]+...+F[n][k];
       设C(i,j)为组合数,即i种元素取j种的方法数 
       所以有:f[n+1][k] = ((n+1)^k)*(x^(n+1)) (二次多项式展开)
                         = x*( C(k,0)*(x^n)+C(k,1)*n*(x^n)+...+C(k,k)*(n^k)*(x^n) ) 
                         = x*( C(k,0)*f[n][0]+C(k,1)*f[n][1]+...+C(k,k)*f[n][k] ) 
       得到递推式就可以用矩阵进行快速幂求解
        |x*1 0................................0|       |f[n][0]|       |f[n+1][0]| 
        |x*1 x*1 0............................0|       |f[n][1]|       |f[n+1][1]| 
        |x*1 x*2 x*1 0........................0|   *   |f[n][2]|   =   |f[n+1][2]| 
        |......................................|       |.......|       |.........| 
        |x*1 x*C(k,1) x*C(k,2)...x*C(k,x) 0...0|       |f[n][k]|       |f[n+1][k]| 
        |......................................|       |.......|       |.........| 
        |x*1 x*C(x,1) x*C(x,2).......x*C(x,x) 0|       |f[n][x]|       |f[n+1][x]| 
        |0................................0 1 1|       |g[n-1] |       | g[ n ]  | 
*/
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll n,x,mod;
ll c[55][55];
ll unit;
/********************************矩阵模板**********************************/
class Matrix {
    public:
        ll a[55][55];
        int n;
        void init() {
            memset(a,0,sizeof(a));//            #出错
            for(int i=0;i<=n;i++){
                for(int j=0;j<=i;j++){
                    a[i][j]=x*c[i][j]%mod;
                }
            }
            a[x+1][x]=a[x+1][x+1]=1;
        }
        Matrix operator +(Matrix b) {
            Matrix c;
            c.n = n;
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                    c.a[i][j] = (a[i][j] + b.a[i][j]) % mod;
            return c;
        }

        Matrix operator +(int x) {
            Matrix c = *this;
            for (int i = 0; i < n; i++)
                c.a[i][i] += x;
            return c;
        }

        Matrix operator *(Matrix b)
        {
            Matrix p;
            p.n = b.n;   
            memset(p.a,0,sizeof p.a);
            for (int i = 0; i < n; i++)
                for (int j = 0; j < n; j++)
                for (int k = 0; k < n; k++)
                    p.a[i][j] = (p.a[i][j] + (a[i][k]*b.a[k][j])%mod) % mod;
            return p;
        }

        Matrix power(int t) {
            Matrix ans,p = *this;
            ans.n = p.n;  
            memset(ans.a,0,sizeof ans.a);
            for(int i=0;i<=n;i++){//初始化ans
                ans.a[i][i]=1;
            }
            while (t) {
                if (t & 1)
                    ans=ans*p;
                p = p*p;
                t >>= 1;
            }
            return ans;
        }
}init;
void Init(){//求组合数
    memset(c,0,sizeof c);
    for(ll i=0;i<=x;i++)  
            c[i][0]=c[i][i]=1;  
    for(ll i=2;i<=x;i++)  
        for(ll j=1;j<i;j++)  
            c[i][j]=((ll)c[i-1][j-1]+c[i-1][j])%mod;
    unit=0;
}
/********************************矩阵模板**********************************/
int main(){
    // freopen("in.txt","r",stdin);
    while(scanf("%lld%lld%lld",&n,&x,&mod)!=EOF&&(n>0,x>0,mod>0)){
        Init();//                #ok
        
        // for(int i=0;i<=x;i++){
            // for(int j=0;j<=x;j++){
                // cout<<c[i][j]<<" ";
            // }
            // cout<<endl;
        // }
        // cout<<endl;
        
        init.n=x+2;
        // cout<<"ok"<<endl;
        init.init();
        
        // for(int i=0;i<=x+1;i++){
            // for(int j=0;j<=x+1;j++){
                // cout<<init.a[i][j]<<" ";
            // }cout<<endl;
        // }
        
        // cout<<"ok"<<endl;
        init=init.power(n);
        
        // for(int i=0;i<=x+1;i++){
            // for(int j=0;j<=x+1;j++){
                // cout<<init.a[i][j]<<" ";
            // }cout<<endl;
        // }
        
        for(int i=0;i<=x;i++){
            unit+=( (x*init.a[x+1][i])%mod );
        }
        printf("%lld\n",(unit+mod)%mod);
    }
    return 0;
}

 

posted @ 2017-02-16 01:48  勿忘初心0924  阅读(190)  评论(0编辑  收藏  举报