SGU 441 Set Division(矩阵快速幂)

时间:2025-01-08 10:36:56

题目链接:http://acm.sgu.ru/status.php

题意:将n个有区别的球放到m个无区别的盒子里,盒子不能为空。不同的方案数。

思路:设f[i][j]表示将前i个球放到j个盒子里,那么f[i][j]=f[i-1][j]*j+f[i-1][j-1]。根据这个建立矩阵。

int n,m;

struct Matrix
{
    i64 a[15][15];

    void init(int x)
    {
        clr(a,0);
        if(x)
        {
            int i;
            FOR1(i,m) a[i][i]=1;
        }
    }

    Matrix operator*(Matrix p)
    {
        Matrix ans;
        ans.init(0);
        int i,j,k;
        FOR1(k,m) FOR1(i,m) FOR1(j,m)
        {
            ans.a[i][j]+=a[i][k]*p.a[k][j]%mod;
            ans.a[i][j]%=mod;
        }
        return ans;
    }

    Matrix Pow(i64 n)
    {
        Matrix ans,p=*this;
        ans.init(1);
        while(n)
        {
            if(n&1) ans=ans*p;
            p=p*p;
            n>>=1;
        }
        return ans;
    }
};

Matrix p;

int main()
{
    Rush(n)
    {
        RD(m);
        int i,j;
        p.init(0);
        FOR1(i,m) p.a[i][i]=i,p.a[i][i+1]=1;
        p=p.Pow(n-1);
        PR(p.a[1][m]);
    }
}