http://codeforces.com/contest/1129/problem/C
#include<bits/stdc++.h> #define fi first #define se second #define INF 0x3f3f3f3f #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define pqueue priority_queue #define NEW(a,b) memset(a,b,sizeof(a)) #define lowbit(x) (x&(-x)) #define si(x) scanf("%d",&x) #define sl(x) scanf("%lld",&x) #define lc (d<<1) #define rc (d<<1|1) const double pi=4.0*atan(1.0); const double e=exp(1.0); const int maxn=1e6+8; typedef long long LL; typedef unsigned long long ULL; const LL mod=1e9+7; const ULL base=1e7+7; using namespace std; LL a[maxn],b[maxn],Next[maxn]; LL dp[3008][3008]; void get_next(int m){ Next[0]=-1; int k=-1; int j=0; while(j<m){ while(k>-1&&b[k]!=b[j]){ k=Next[k]; } if(b[k]==b[j]||k==-1){ k++; } Next[++j]=k; } } bool kmp(int n,int m){ int k=0; for(int i=n-m+1;i<=n;i++){ b[k++]=a[i]; } get_next(m); k=0; for(int i=0;i<n;i++) { while(k>0&&b[k]!=a[i]){ k=Next[k]; } if(b[k]==a[i]){ k++; } if(k==m){ return 1; } } return 0; } bool check(int l){ if(a[l]==0&&a[l+1]==0&&a[l+2]==1&&a[l+3]==1) return 0; if(a[l]==0&&a[l+1]==1&&a[l+2]==0&&a[l+3]==1) return 0; if(a[l]==1&&a[l+1]==1&&a[l+2]==1&&a[l+3]==0) return 0; if(a[l]==1&&a[l+1]==1&&a[l+2]==1&&a[l+3]==1) return 0; return 1; } int main(){ int n; LL sum=1; scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d",&a[i]); if(i==0){ dp[0][0]=1; printf("1\n"); } else{ int l=1,r=i; int ans=0; while(l<=r){ int mid=(l+r)>>1; if(kmp(i,mid)){ l=mid+1; ans=max(ans,mid); } else{ r=mid-1; } } dp[i][i]=1; if(i>0) dp[i-1][i]=1; if(i>1) dp[i-2][i]=1; if(i>2&&check(i-3)) dp[i-3][i]=1; for(int j=i-4;j>=0;j--){ dp[j][i]+=dp[j][i-4]*dp[i-3][i]; dp[j][i]%=mod; } for(int j=i-3;j>=0;j--){ dp[j][i]+=dp[j][i-3]*dp[i-2][i]; dp[j][i]%=mod; } for(int j=i-2;j>=0;j--){ dp[j][i]+=dp[j][i-2]*dp[i-1][i]; dp[j][i]%=mod; } for(int j=i-1;j>=0;j--){ dp[j][i]+=dp[j][i-1]*dp[i][i]; dp[j][i]%=mod; } for(int j=i-ans;j>=0;j--){ sum+=dp[j][i]; sum%=mod; } printf("%lld\n",sum); } } }