题目

魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 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 共有多少种生成魔咒。

输入格式

第一行一个整数 n。

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

1≤n≤100000。,用来表示魔咒字符的数字 x 满足 1≤x≤10^9

输出格式

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

输入样例

7

1 2 3 3 3 1 2

输出样例

1

3

6

9

12

17

22

题解

用到后缀自动机的一个性质:

节点u所代表的子串数 = step[u] - step[pre[u]]

原因:

显然u所代表的子串数为[min(u),max(u)],其中min,max均代表从根到u的路径的长度最值

而且有这样一个性质:u父亲的max(fa) = min(u) - 1

所以u代表的子串数可以写成如上所示

我们只需要在每次建立父亲指针和断开父亲指针时维护答案就好了

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define BUG(s,n) for (int i = 1; i <= (n); i++) cout<<s[i]<<' '; puts("");
using namespace std;
const int maxn = 200005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 3) + (out << 1) + c - '0'; c = getchar();}
return out * flag;
}
map<int,int> ch[maxn];
int pre[maxn],step[maxn],cnt,last,n;
LL ans;
int upd(int u){return step[u] - step[pre[u]];}
void ins(int x){
int p = last,np = ++cnt;
last = np; step[np] = step[p] + 1;
while (p && !ch[p].count(x)) ch[p][x] = np,p = pre[p];
if (!p) pre[np] = 1,ans += upd(np);
else {
int q = ch[p][x];
if (step[q] == step[p] + 1) pre[np] = q,ans += upd(np);
else {
int nq = ++cnt; step[nq] = step[p] + 1;
ch[nq] = ch[q]; pre[nq] = pre[q]; ans += upd(nq) - upd(q);
pre[np] = pre[q] = nq; ans += upd(np) + upd(q);
while (p && ch[p][x] == q) ch[p][x] = nq,p = pre[p];
}
}
}
int main(){
n = read(); int x; cnt = last = 1;
REP(i,n) x = read(),ins(x),printf("%lld\n",ans);
return 0;
}

BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】的更多相关文章

  1. BZOJ4516: [Sdoi2016]生成魔咒 后缀自动机

    #include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...

  2. [bzoj4516][Sdoi2016]生成魔咒——后缀自动机

    Brief Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生 ...

  3. BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]

    4516: [Sdoi2016]生成魔咒 题意:询问一个字符串每个前缀有多少不同的子串 做了一下SDOI2016R1D2,题好水啊随便AK 强行开map上SAM 每个状态的贡献就是\(Max(s)-M ...

  4. BZOJ 4516: [Sdoi2016]生成魔咒 后缀自动机 性质

    http://www.lydsy.com/JudgeOnline/problem.php?id=4516 http://blog.csdn.net/doyouseeman/article/detail ...

  5. BZOJ 4516 [Sdoi2016]生成魔咒 ——后缀自动机

    本质不同的字串,考虑SA的做法,比较弱,貌似不会. 好吧,只好用SAM了,由于后缀自动机的状态最简的性质, 所有不同的字串就是∑l[i]-l[fa[i]], 然后后缀自动机是可以在线的,然后维护一下就 ...

  6. BZOJ.4516.[SDOI2016]生成魔咒(后缀自动机 map)

    题目链接 后缀数组做法见这. 直接SAM+map.对于每个节点其产生的不同子串数为len[i]-len[fa[i]]. //15932kb 676ms #include <map> #in ...

  7. BZOJ4516: [Sdoi2016]生成魔咒(后缀数组 set RMQ)

    题意 题目链接 Sol 毒瘤SDOI 终于有一道我会做的题啦qwq 首先,本质不同的子串的个数 $ = \frac{n(n + 1)}{2} - \sum height[i]$ 把原串翻转过来,每次就 ...

  8. [SDOI2016]生成魔咒(后缀自动机)

    /* 水题, 根据性质做就行, nq不会对答案产生贡献, 那么只算p的贡献就好了 */ #include<cstdio> #include<algorithm> #includ ...

  9. [SDOI2016] 生成魔咒 - 后缀数组,平衡树,STL,时间倒流

    [SDOI2016] 生成魔咒 Description 初态串为空,每次在末尾追加一个字符,动态维护本质不同的子串数. Solution 考虑时间倒流,并将串反转,则变为每次从开头删掉一个字符,即每次 ...

随机推荐

  1. EM理解(转)

    EM是我一直想深入学习的算法之一,第一次听说是在NLP课中的HMM那一节,为了解决HMM的参数估计问题,使用了EM算法.在之后的MT中的词对齐中也用到了.在Mitchell的书中也提到EM可以用于贝叶 ...

  2. modprobe与insmod的区别

    linux设备驱动有两种加载方式insmod和modprobe,下面谈谈它们用法上的区别1.insmod一次只能加载特定的一个设备驱动,且需要驱动的具体地址.写法为:        insmod dr ...

  3. C# FileInfo 类

    FileInfo类不像File类,它没有静态方法,仅可用于实例化的对像.FileInfo对像表示在磁盘或网络位置的文件,注意它不是流,为了读写文件,必须创建Stream对像. fileInfo类提供了 ...

  4. detection in video and image

    video中的detection,背景更加复杂,目标更加不聚焦,同时由于图片分辨率低于图像,因此更加难做. image中的Detection,背景相对简单些,目标更加聚焦,同时图片分辨率高,因此更加容 ...

  5. es6中的promise解读

    目录 什么是promise? promise的优点 回调地狱问题  Promise的三种状态 一个简单的promise promise中的then 利用promise解决回调地狱 promise的链式 ...

  6. 项目十八-Hadoop+Hbase分布式集群架构“完全篇”

    本文收录在Linux运维企业架构实战系列 前言:本篇博客是博主踩过无数坑,反复查阅资料,一步步搭建,操作完成后整理的个人心得,分享给大家~~~ 1.认识Hadoop和Hbase 1.1 hadoop简 ...

  7. DNS服务初步搭建

    一.准备DNS服务环境 选择 bind dns服务软件包 直接yum安装 bind 和 bind-utils 工具包,测试机器安装bind-utils测试工具包. 服务程序名为 named 二.配置D ...

  8. 正则表达式-基础知识Review

    正则表达式(Regular Expression)是计算机科学的一个概念. 正则表达式使用单个字符窜来描述.匹配一系列符合某个句法规则的字符窜. 在很多文本编辑器里, 正则表达式通常用来被检索替换哪些 ...

  9. RPC框架 - thrift 客户端

    -------客户端程序 ------ 下载    下载 thrift 源代码包    下载 thrift 的bin包 准备描述文件(使用源代码包的示例文件)    \thrift-0.10.0\tu ...

  10. MTCNN学习进展

    20190618 截止今日,学习了MTCNN预测部分的内容,包括三个网络输入输出之类的东西. 之后需要进一步学习的,NMS原理鞋机,MTCNN训练过程细节,损失函数细节