来自FallDream的博客,未经允许,请勿转载,谢谢。


[bzoj4870][Shoi2017]组合数问题

与sdoi2017那道题神似

用f[i]表示选出的数量膜k等于i的方案数,容易构造转移矩阵,复杂度k^3log(nk)

也可以构造一个生成函数 复杂度k^2log(nk) 

理论上可以优化到klognlogk 但常数巨大。

#include<iostream>
#include<cstdio>
#define MN 50
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

int n,p,k,r,A[MN+5],B[MN+5],C[MN+5];

void Mul(int*a,int*b)
{
    for(int i=0;i<k;++i) if(a[i])
        for(int j=0;j<k;++j)
            C[(i+j)%k]=(C[(i+j)%k]+1LL*a[i]*b[j])%p; 
    for(int i=0;i<k;++i) a[i]=C[i],C[i]=0;
}

int main()
{
    n=read();p=read();k=read();r=read();
    A[0]=1;B[0]=1;++B[1%k];
    for(long long K=1LL*n*k;K;K>>=1,Mul(B,B))
        if(K&1) Mul(A,B); 
    printf("%d\n",A[r]);
    return 0;
}

相关文章:

  • 2021-07-08
  • 2022-03-02
  • 2021-09-30
  • 2022-02-28
  • 2021-12-29
  • 2022-02-24
  • 2021-07-31
  • 2022-12-23
猜你喜欢
  • 2021-08-19
  • 2022-02-21
  • 2021-10-27
  • 2021-07-10
  • 2021-08-19
  • 2021-12-01
相关资源
相似解决方案