洛谷P5173 传球(暴力)

传送门

真·暴力艹过去

不难发现这个转移其实就是一个循环卷积的形式,设有多项式\(A=x+x^{n-1}\),那么\(f_m=f_0\times A^m\)

直接暴力计算并卡常就行了

//minamoto
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
const int N=10005,P=1e9+7;
inline int add(R int x,R int y){return x+y>=P?x+y-P:x+y;}
inline int dec(R int x,R int y){return x-y<0?x-y+P:x-y;}
inline int mul(R int x,R int y){return 1ll*x*y-1ll*x*y/P*P;}
int n,m,A[N],ans[N],tmp[N];
void Mul(int *A,int *B,int n){
    memset(tmp,0,sizeof(int)*(2*n));
    fp(i,0,n-1)if(A[i])fp(j,0,n-1)
    tmp[i+j]=add(tmp[i+j],mul(A[i],B[j]));
    fp(i,0,n-1)A[i]=add(tmp[i],tmp[i+n]);
}
int main(){
//	freopen("testdata.in","r",stdin);
    scanf("%d%d",&n,&m);
    ++A[1],++A[n-1],++ans[0];
    for(;m;m>>=1,Mul(A,A,n))if(m&1)Mul(ans,A,n);
    printf("%d\n",ans[0]);
    return 0;
}
posted @ 2019-01-15 12:59  bztMinamoto  阅读(146)  评论(0编辑  收藏  举报
Live2D