[JZOJ5215]【HEOI、SXOI2017】组合数问题

来源:互联网 发布:java程序员的简历 编辑:程序博客网 时间:2024/06/06 05:10

Description


i=0ik+rnkCik+rnkmodp

其中1n109,0r<k50,2p2301

Solution

考虑组合数的实际意义
有nk个物品,取的物品数模k等于r的方案数

Fi,j表示前i个物品,选的个数模k等于j的方案数

显然

Fi,j=Fi1,j+Fi1,j1

特别的,当j=0
Fi,0=Fi1,0+Fi1,k1

显然可以直接矩乘优化

Code

#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <iostream>#include <cmath>#define fo(i,a,b) for(int i=a;i<=b;i++)#define fod(i,a,b) for(int i=a;i>=b;i--)#define LL long long #define N 1000005using namespace std;LL n,p,k,r;struct node{    LL a[51][51];    friend node operator *(node x,node y)    {        node c;        memset(c.a,0,sizeof(c.a));        fo(i,0,k-1)        {            fo(j,0,k-1)            {                fo(q,0,k-1)                {                    (c.a[i][j]+=x.a[i][q]*y.a[q][j]%p)%=p;                }            }        }        return c;    }}s,t;node ksm(node k,LL n){    if(n==1) return k;    node s=ksm(k,n/2);    return (n%2)?s*s*k:s*s;}int main(){    cin>>n>>p>>k>>r;    fo(i,1,k-1) t.a[i][i]++,t.a[i-1][i]++;    t.a[0][0]++,t.a[k-1][0]++;    s.a[0][0]=1;    t=ksm(t,n*k);    s=s*t;    printf("%lld\n",s.a[0][r]);}
原创粉丝点击