Berlekamp-Massey Algorithm [for Team Problem 5525]
Input:
第一行为两个正整数n,m
第二行为n个整数a1..an
最后一行为一个正整数k
Output:
为一个整数,代表方案数对1000000007取模的值
Sample Input
5 3 1 1 2 0 2 2
Sample Output
3
来自毛爷爷17年论文
Berlekamp-Massey Algorithm直接开算
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=2010,mod=(int)1e9+7; 5 ll Base[N][N],a[N],MM[N]; 6 int M,S; 7 int n,m,k,d[N]; 8 bool vis[N]; 9 ll FPM(ll a,ll b,ll p){ 10 ll res=1ll; 11 for(;b;b>>=1,a=a*a%p) 12 if(b&1)res=res*a%p; 13 return res; 14 } 15 ll inv(ll v,ll p){return FPM(v,p-2,p);} 16 void BMA1(){ 17 int l=n+1; 18 S=M=n; 19 ll u=0,rev=1; 20 Base[n][n]=1;Base[n+1][n+1]=1; 21 d[n]=n;d[n+1]=n+1; 22 for(int i=n-1;~i;--i,u=0){ 23 for(int j=0;j<=n;++j) 24 (u+=Base[i+1][j]*a[n-j]%m)%=m; 25 for(int j=0;j<n;++j){ 26 Base[i][j]=(Base[i+1][j+1]-u*rev%m*Base[l][j+1]%m+m)%m; 27 } 28 if(u&&d[i+1]<d[l]){ 29 d[i]=d[l]-1; 30 l=i+1,rev=inv(u,m); 31 } 32 else d[i]=d[i+1]-1; 33 if(d[i]<d[M])M=i; 34 } 35 } 36 ll Calc(){ 37 ll ans=0; 38 memcpy(MM,Base[M],sizeof MM); 39 vis[M]=1; 40 for(int i=M+1,flag=1;i<n;++i,flag=1){ 41 for(int j=n*2;j>=1;--j) 42 MM[j]=MM[j-1]; 43 MM[0]=0; 44 for(int j=0;j<=2*n;++j) 45 if(MM[j]!=(j<=n?Base[i][j]:0)){ 46 flag=0; 47 break; 48 } 49 vis[i]=flag; 50 } 51 for(int i=0;i<n;++i) 52 if(!vis[i]&&d[i]<d[S]) 53 S=i; 54 for(int i=0;i<=k;++i){ 55 ll res=FPM(m,max(i-d[M],0)+max(i-d[S],0),mod); 56 (res*=(FPM(m,(i>=d[M])+(i>=d[S]),mod)-1+mod)%mod)%=mod; 57 (ans+=res)%=mod; 58 } 59 return (ans+1)%mod; 60 } 61 int main(){ 62 scanf("%d%d",&n,&m); 63 for(int i=0;i<n;++i)scanf("%lld",a+i); 64 scanf("%d",&k); 65 BMA1(); 66 cout<<Calc()<<endl; 67 return 0; 68 }
目前跑过了标算
Upd:2019.8.8
洛谷上有一道板子题,线性递推的优化原理都在题解里有解释,菜鸡的我就不丢人现眼了