pro:

维护一个01字符串,支持在结尾动态加字符。

每一个长度<=4的01串可以对应一个字母(有几个特例除外)

每次操作后询问,这个字符串的所有子串一共可以对应出多少种本质不同的字符串。

sol:

考虑dp。

dp[i][j]表示从i这个字符开始到当前倒数第j位这个01串,可以划分为多少不同的字符串。

每次只需要更新一下从1到i的每一个dp数组即可。

但时考虑本质不同这个问题。

显然每一种字母串对应唯一的01串。

因此我们只需要对相同的01子串只统计一次即可。

这里用SAM进行判重即可。

#include<bits/stdc++.h>
#define N 22000
#define L 20000
#define eps 1e-7
#define inf 1e9+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline int read()
{
char ch=0;
int x=0,flag=1;
while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*flag;
}
const ll mo=1e9+7;
int f[N],id[N],dp[N][8];
int root=1,size=1,last=1;
struct node{int pos,len,lnk,nxt[2];}s[N];
void build(int k)
{
int cur=++size,p=last;last=cur;
s[cur].len=s[p].len+1;s[cur].pos=s[cur].len;
while(p&&!s[p].nxt[k])s[p].nxt[k]=cur,p=s[p].lnk;
if(!p){s[cur].lnk=root;return;}
int q=s[p].nxt[k];
if(s[q].len==s[p].len+1){s[cur].lnk=q;return;}
else
{
int clone=++size;
s[clone]=s[q];s[clone].len=s[p].len+1;
while(p&&s[p].nxt[k]==q)s[p].nxt[k]=clone,p=s[p].lnk;
s[q].lnk=s[cur].lnk=clone;
}
}
int main()
{
srand(time(0));
int n=read(),ans=0;
for(int i=1;i<=n;i++)f[i]=read(),build(f[i]);
for(register int o=1;o<=n;o++)
{
id[o]=root;
for(register int i=1;i<o;i++)
{
for(register int j=4;j>=1;j--)dp[i][j]=dp[i][j-1];dp[i][0]=0;
for(register int j=1;j<=4;j++)if(o-i+1>=j)
{
if(j==4)
{
if(f[o-3]==0&&f[o-2]==0&&f[o-1]==1&&f[o]==1)continue;
if(f[o-3]==0&&f[o-2]==1&&f[o-1]==0&&f[o]==1)continue;
if(f[o-3]==1&&f[o-2]==1&&f[o-1]==1&&f[o]==0)continue;
if(f[o-3]==1&&f[o-2]==1&&f[o-1]==1&&f[o]==1)continue;
}
dp[i][0]=(dp[i][0]+dp[i][j])%mo;
}
int x=id[i];
if(x!=-1){if(s[x].nxt[f[o]])x=s[x].nxt[f[o]];else x=-1;}
if(x==-1||o==s[x].pos)ans=(ans+dp[i][0])%mo;id[i]=x;
}
dp[o][0]=dp[o][1]=1;
int x=id[o];
if(x!=-1){if(s[x].nxt[f[o]])x=s[x].nxt[f[o]];else x=-1;}
if(x==-1||o==s[x].pos)ans=(ans+dp[o][0])%mo;id[o]=x;
printf("%d\n",ans);
}
return 0;
}

最新文章

  1. jquery遍历table获取td单元格的值
  2. Android中Shape的使用
  3. su- 与su的区别
  4. android:installLocation 解析
  5. Android之自定义控件-下拉刷新
  6. DOM_04之常用对象及BOM
  7. Instant Complexity(模拟,递归)
  8. TalkingDataGame SDK在android Lua上的使用
  9. Activity中的startActivityResult,setResult,finish,onActivityResult的关系
  10. javascript 我是广告
  11. CodeIgniter中的session处理
  12. eclipse 配置ssh
  13. 类StringBuilder
  14. 学习随笔:Django 补充及常见Web攻击 和 ueditor
  15. 剑指offer面试题26:复杂链表的复制
  16. FutureBuilder的使用以及防止FutureBuilder不必要重绘的两种方法
  17. ETCD&amp;Flannel安装
  18. 使用poi读写excel文件
  19. 20155238 2016-2017-2《Java程序设计》课程总结
  20. windows版本SourceTree免登陆初始设置

热门文章

  1. #2718. 「NOI2018」归程 kruskal重构树
  2. Maven集成Tomcat插件
  3. Lazarus分体式改成一体式窗口
  4. HDFS 的垃圾回收配置
  5. Bytom矿池接入协议指南
  6. Spring Cloud各组件超时总结
  7. JavaScript 调试常见报错以及原因
  8. Shell 脚本批量创建数据库表
  9. sticky-footer的三种解决方案
  10. IO模型——IO多路复用机制