您的位置:首页 > 其它

[bzoj4870][Shoi2017]组合数问题

2017-05-22 21:31 423 查看
来自FallDream的博客,未经允许,请勿转载,谢谢。



与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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: