题目

魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示。例如可以将魔咒字符 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. 机器学习_线性回归和逻辑回归_案例实战:Python实现逻辑回归与梯度下降策略_项目实战:使用逻辑回归判断信用卡欺诈检测

    线性回归: 注:为偏置项,这一项的x的值假设为[1,1,1,1,1....] 注:为使似然函数越大,则需要最小二乘法函数越小越好 线性回归中为什么选用平方和作为误差函数?假设模型结果与测量值 误差满足 ...

  2. python_19_编码解码

    msg="我爱北京天安门" #字符串转成Byte类型 print(msg.encode())#encode 编码 print(msg.encode(encoding="u ...

  3. Vue源码学习二 ———— Vue原型对象包装

    Vue原型对象的包装 在Vue官网直接通过 script 标签导入的 Vue包是 umd模块的形式.在使用前都通过 new Vue({}).记录一下 Vue构造函数的包装. 在 src/core/in ...

  4. tomcat修改默认主页, 前段项目放到tomcat下,浏览器输入ip加端口后,直接到项目主页

    1,将 项目 放到 tomcat 的webapps 文件夹下 2, 修改conf 下的 server.xml , 找到 <Host name="localhost" appB ...

  5. HTTP 配置与编译安装

    目录 HTTP 配置与编译安装 HTTP 相关配置 DSO 定义'Main' Server 的文档页面路径 定义站点主页面 站点访问控制常见机制 基于源地址实现访问控制 日志设定 设定默认字符集 定义 ...

  6. python笔记-dict字典的方法2

    #!/usr/bin/env python #-*- coding:utf-8 -*- ''' 概述: 使用键值(key-value)存储,具有极快的查找速度 注意:字典是无序的 key的特性: 1. ...

  7. 09.1.VUE学习之watch监听属性变化实现类百度搜索栏功能ajax异步请求数据,返回数组

    09.1html里 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> < ...

  8. psutil——获取系统信息的Python第三方模块

    本文摘自廖雪峰大神个人网站:https://www.liaoxuefeng.com/wiki/1016959663602400/1183565811281984 用Python来编写脚本简化日常的运维 ...

  9. C、C++混合调用——博客收藏

    C与C++接口相互调用:https://www.cnblogs.com/feige1314/p/7890982.html C.C++混合调用:https://www.cnblogs.com/xuany ...

  10. Linux安全层详解

    1 bastion(安全堡垒系统)通常配置两个服务: 1 服务定义系统的功能: 2 服务支持远程访问: 原则: 1 不需要某个软件卸载掉: 2 需要某个软件但不使用就不要激活: 为各个bastion系 ...