生成魔咒

Time Limit: 10 Sec  Memory Limit: 128 MB
[Submit][Status][Discuss]

Description

  魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 1、2 拼凑起来形成一个魔咒串 [1,2]。
  一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒。
  例如 S=[1,2,1] 时,它的生成魔咒有 [1]、[2]、[1,2]、[2,1]、[1,2,1] 五种。
  S=[1,1,1] 时,它的生成魔咒有 [1]、[1,1]、[1,1,1] 三种。
  最初 S 为空串。共进行 n 次操作,每次操作是在 S 的结尾加入一个魔咒字符。
  每次操作后都需要求出,当前的魔咒串 S 共有多少种生成魔咒。

Input

  第一行一个整数 n。
  第二行 n 个数,第 i 个数表示第 i 次操作加入的魔咒字符。

Output

  输出 n 行,每行一个数。第 i 行的数表示第 i 次操作后 S 的生成魔咒数量

Sample Input

  7
  1 2 3 3 3 1 2

Sample Output

  1
  3
  6
  9
  12
  17
  22

HINT

  1≤n≤100000

Main idea

  询问在加入每一个字符后当前有多少个本质不同的子串。

Solution

  直接用SAM,根据SAM的性质,每次增多的子串个数就是len[New] - len[fa[New]]

Code

 #include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<map>
using namespace std;
typedef long long s64; const int ONE = ;
const int INF = ; int n,x;
s64 Ans; int get()
{
int res=,Q=;char c;
while( (c=getchar())< || c> )
if(c=='-')Q=-;
res=c-;
while( (c=getchar())>= && c<= )
res=res*+c-;
return res*Q;
} struct SAM
{
map <int, int> a[ONE];
int len[ONE], fa[ONE];
int last, cnt;
SAM() {last = cnt = ;}
void Add(int c)
{
int x = last, New = last = ++cnt;
len[New] = len[x] + ;
while(x && !a[x][c]) a[x][c] = New, x = fa[x];
if(!x) {fa[New] = ; Ans += len[New] - len[fa[New]]; return;} int q = a[x][c];
if(len[x] + == len[q]) fa[New] = q;
else
{
int Nq = ++cnt; len[Nq] = len[x] + ;
a[Nq] = a[q];
fa[Nq] = fa[q];
fa[New] = fa[q] = Nq;
while(a[x][c] == q) a[x][c] = Nq, x = fa[x];
}
Ans += len[New] - len[fa[New]];
}
}S; int main()
{
n = get();
while(n--)
{
x = get();
S.Add(x);
printf("%lld\n", Ans);
} }

最新文章

  1. C语言中const的正确用法
  2. [jQuery学习系列一]1-选择器与DOM对象
  3. Gradle: The New Android Build System
  4. unix的策略与机制
  5. Tabbar视图切换,返回上一视图,添加item
  6. 利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)
  7. hdu 3695 Computer Virus on Planet Pandora(AC自己主动机)
  8. POI 3.8读取2003与2007格式EXCEL(xls、xlsx)
  9. n的m划分 整数拆分问题
  10. 通过 JS 脚本去除csdn广告
  11. python-----短信、电话告警
  12. 学习Unity -- 理解依赖注入(IOC)三种方式依赖注入
  13. centos查看系统版本
  14. 无线网卡连接网络后共享给本地有线网卡使用(Win10)
  15. RENAME方法进行分区改造
  16. 20165305 苏振龙《Java程序设计》第八周课上测试补做
  17. C# 中的委托和事件 --转载
  18. 搜索引擎ElasticSearch系列(三): ElasticSearch2.4.4 bigdesk插件安装
  19. Codeforces 1088E 树形dp+思维
  20. ionic准备之angular基础——dom操作相关(6)

热门文章

  1. 第十七次ScrumMeeting会议
  2. II 3.1 连接到服务器
  3. 详解实现Android中实现View滑动的几种方式
  4. Swift-创建UIButton(其他UI组件雷同)
  5. linux 安装 bitnamid-redmine
  6. 网页添加提示音,用setInterval
  7. Eclipse闪退解决方案
  8. matlab 并行运算【转】
  9. zoj3209-Treasure Map
  10. Python Collections详解