zoukankan      html  css  js  c++  java
  • 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

    洛谷上有一道板子题,线性递推的优化原理都在题解里有解释,菜鸡的我就不丢人现眼了

  • 相关阅读:
    再谈树形dp
    洛谷 P3627 [APIO2009]抢掠计划
    树状数组
    树形dp 入门
    洛谷P2014 选课
    洛谷P2015 二叉苹果树
    9 vue.js 被观察数组的变异方法
    8 vue的v-model指令学习
    7vue-事件修饰符
    6.vue事件绑定-click
  • 原文地址:https://www.cnblogs.com/ndqzhang1111/p/6947270.html
Copyright © 2011-2022 走看看