bzoj 4870: [Shoi2017]组合数问题

来源:互联网 发布:php周末培训班 编辑:程序博客网 时间:2024/06/05 03:13

题意:

求题面上那个乱七八糟的柿子。

题解:

其实是道大傻逼题
千万不要像我一样被那个玩意吓坏了。
地球版题意:在n*k个物品中选若干个物品,使其数量mod p=r
然后dp+矩乘。
我真是大傻逼
code:

#include<cstdio>#include<cstdlib>#include<cstring>#include<iostream>#define LL long longusing namespace std;struct node{    LL n,m,a[55][55];}em,f;LL n,mod,k,r;node operator * (node a,node b){    node ans;ans=em;    ans.n=a.n;ans.m=b.m;    for(LL i=0;i<a.n;i++)        for(LL j=0;j<b.m;j++)            for(LL k=0;k<a.m;k++)                (ans.a[i][j]+=a.a[i][k]*b.a[k][j])%=mod;    return ans;}node operator ^ (node a,LL b){    node ans;ans=em;    ans.n=a.n;ans.m=a.m;    for(LL i=0;i<a.n;i++) ans.a[i][i]=1;    while(b)    {        if(b&1) ans=ans*a;        a=a*a;b>>=1;    }    return ans;}int main(){    scanf("%lld %lld %lld %lld",&n,&mod,&k,&r);    f.n=1;f.m=k;f.a[0][0]=1;    node a;a.n=a.m=k;    for(LL i=0;i<k;i++)        a.a[i][i]++,a.a[(i-1+k)%k][i]++;    f=f*(a^(n*k));    printf("%lld",f.a[0][r]);}
原创粉丝点击