题意:给定字符串,求每个前缀的本质不同的子串数量。字符集1e9。

解:在线构造后缀自动机并统计答案。

答案就是∑len[i] - len[fail[i]]

每次增加的时候,至多对三个节点有影响。然而把Q分裂为nQ本质不同的子串数没变。

于是增加的只有len[np] - len[fail[np]]

map维护转移边。

 #include <cstdio>
#include <map> typedef long long LL;
const int N = ; int len[N], fail[N], last, top;
LL ans;
std::map<int, int> mp[N]; inline void init() {
top = last = ;
return;
} inline void insert(int f) {
int p = last, np = ++top;
last = np;
len[np] = len[p] + ;
while(p && !mp[p].count(f)) {
mp[p][f] = np;
p = fail[p];
}
//printf("p = %d \n", p);
if(!p) {
fail[np] = ;
ans += len[np];
//printf("1 : ans += %d \n", len[np]);
}
else {
int Q = mp[p][f];
//printf("Q = %d \n", Q);
if(len[Q] == len[p] + ) {
fail[np] = Q;
ans += len[np] - len[Q];
//printf("2 : ans += %d \n", len[np] - len[Q]);
}
else {
int nQ = ++top;
len[nQ] = len[p] + ;
fail[nQ] = fail[Q];
fail[Q] = fail[np] = nQ;
mp[nQ] = mp[Q];
while(mp[p].count(f) && mp[p][f] == Q) {
mp[p][f] = nQ;
p = fail[p];
}
ans += len[np] - len[nQ];
}
}
return;
} int main() {
int n;
scanf("%d", &n);
init();
for(int i = , x; i <= n; i++) {
scanf("%d", &x);
insert(x);
printf("%lld\n", ans);
} return ;
}

AC代码

洛谷P4070 生成魔咒的更多相关文章

  1. 洛谷 P4070 [SDOI2016]生成魔咒 解题报告

    P4070 [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 \(1\).\(2\) 拼凑起来形成一个魔咒串 \([1,2]\). 一个魔咒 ...

  2. P4070 [SDOI2016]生成魔咒

    题目地址:P4070 [SDOI2016]生成魔咒 相信看到题目之后很多人跟我的思路是一样的-- 肯定要用 SA(P3809 [模板]后缀排序) 肯定要会求本质不同的子串个数(P2408 不同子串个数 ...

  3. bzoj4516 / P4070 [SDOI2016]生成魔咒

    P4070 [SDOI2016]生成魔咒 后缀自动机 每插入一个字符,对答案的贡献为$len[last]-len[fa[last]]$ 插入字符范围过大,所以使用$map$存储. (去掉第35行就是裸 ...

  4. 【LG4070】[SDOI2016]生成魔咒

    [LG4070][SDOI2016]生成魔咒 题面 洛谷 题解 如果我们不用在线输的话,那么答案就是对于所有状态\(i\) \[ \sum (i.len-i.fa.len) \] 现在我们需要在线询问 ...

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

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

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

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

  7. [SDOI2016]生成魔咒

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

  8. BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay

    BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...

  9. [BZOJ 4516] [SDOI 2016] 生成魔咒

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

随机推荐

  1. 使用getopts处理输入参数

    在编写shell脚本中,需要输入参数,使用过程中,getopts更加方便.可以很好的处理用户输入的参数和参数值. 参加如下一段脚本: #!/bin/bash while getopts ": ...

  2. 除了binlog2sql工具外,使用python脚本闪回数据(数据库误操作)

    利用binlog日志恢复数据库误操作数据 在人工手动进行一些数据库写操作的时候(比方说数据修改),尤其是一些不可控的批量更新或删除,通常都建议备份后操作.不过不怕万一,就怕一万,有备无患总是好的.在线 ...

  3. $.ajax的async设置true和false的区别一点笔记

    async的默认值是true 当async为true时,为异步请求 如果一个$.ajax的函数在另一个函数中调用,不一定会等该函数调用完再加载完函数 导致产生空值的问题 而在JS函数中调用$.ajax ...

  4. memcach 命令行

    1. cmd上登录memcache # telnet 127.0.0.1 11211   2. 列出所有items stats items     3. 通过itemid获取key 接下来基于列出的i ...

  5. QTP自动化测试-点滴-步骤

    1 添加 test 2 设置 整个测试项目的 setting -数据表位置 3 添加 引用 方法文件 4 添加 action 5 添加 action 对应的 repository 控件库 6 录制.整 ...

  6. Java多线程之实现Runnable接口

    package org.study2.javabase.ThreadsDemo.runnable; /** * @Auther:GongXingRui * @Date:2018/9/18 * @Des ...

  7. Spring Boot 构建电商基础秒杀项目 (五) 用户注册

    SpringBoot构建电商基础秒杀项目 学习笔记 UserService 添加 void register(UserModel userModel) throws BusinessException ...

  8. hdu-1058(map)

    题意:输出第n个能拆分成由,2,3,5,7中的一个或者多个组成的数: 解题思路:a[i+1]=a[i]*2;a[i+2]=a[i]*3;a[i+3]=a[i]*5;a[i+4]=a[i]*7;然后把重 ...

  9. 训练赛-Eyad and Math

    题意:给你四个数,求出a^b是否小于c^d,是的话输出<,否则输出>; 思路:因为数据很大,所以我们需要降低数据的规模,比如用一个log10()函数,这就能解决了,注意,要用scanf输入 ...

  10. setTimeout运行机制简要理解

    经典例子辅助理解setTimeout工作原理 运行结果: 约1秒后输出:1,再过约1秒后输出:2,接着才立即输出:时间流逝了: 2002 毫秒最后输出:时间又流逝了: 2003 毫秒 在现有浏览器环境 ...