4870: [Shoi2017]组合数问题
Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 723 Solved: 379
[Submit][Status][Discuss]
Description
Input
第一行有四个整数 n, p, k, r,所有整数含义见问题描述。
1 ≤ n ≤ 10^9, 0 ≤ r < k ≤ 50, 2 ≤ p ≤ 2^30 − 1
Output
一行一个整数代表答案。
Sample Input
2 10007 2 0
Sample Output
8
Source
#include<iostream> #include<cstdio> #include<algorithm> #include<cmath> #include<cstring> #define N 50 #define ll long long using namespace std; int read() { int f=1,x=0;char s=getchar(); while(s<‘0‘ || s>‘9‘){if(s==‘-‘)f=-1;s=getchar();} while(s>=‘0‘ && s<=‘9‘){x=x*10+s-‘0‘;s=getchar();} return x*f; } ll n,mod,k,r; struct matrix { ll a[N][N]; inline void clear() { memset(a,0,sizeof(a)); } inline void print() { for(int i=0;i<k;i++) { for(int j=0;j<k;j++)printf("%d ",a[i][j]); printf("\n"); } printf("\n"); } }e,tr,ans; inline matrix operator * (matrix a,matrix b) { matrix c; c.clear(); for(int i=0;i<k;i++)for(int j=0;j<k;j++)for(int s=0;s<k;s++) c.a[i][j]=(c.a[i][j]+(a.a[i][s]%mod)*(b.a[s][j]%mod))%mod; return c; } inline matrix pow(matrix a,ll p) { matrix ret=e; while(p) { if(p&1)ret=ret*a; a=a*a; p>>=1; } return ret; } /* void debug() { matrix x=e; for(int i=0;i<n;i++)x=x*tr,x.print(); }*/ int main() { scanf("%lld%lld%lld%lld",&n,&mod,&k,&r); ans.a[0][0]=1; for(int i=0;i<k;i++) e.a[i][i]=1,tr.a[i][i]++,tr.a[i][(i+1)%k]++; n*=k; //debug(); tr=pow(tr,n); ans=ans*tr; //ans.print(); printf("%lld\n",(ans.a[0][r]+mod)%mod); //tr=tr*tr; //tr.print(); return 0; }