题意:给定字符串,求每个前缀的本质不同的子串数量。字符集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. 手机浏览器 - 如何消除<a>标签在点击时的蓝色底色?

    为a标签设置这个样式: a{-webkit-tap-highlight-color:transparent};

  2. CSS硬件加速的好与坏

    本文翻译自Ariya Hidayat的Hardware Accelerated CSS: The Nice vs The Naughty.感谢Kyle He帮助校对. 每个人都痴迷于60桢每秒的顺滑动 ...

  3. 转《vue引入第三方js库》

    一.绝对路径直接引入,全局可用 二.绝对路径直接引入,配置后,import 引入后再使用 三.webpack中配置 alias,import 引入后再使用 四.webpack 中配置 plugins, ...

  4. Hbase API

  5. java中的缓冲流!

    package cn.zhozuohou; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; impor ...

  6. MIUI(ADUI)关闭广告推送步骤方法

    MIUI自从到了版本MIUI8之后,系统增加了各种推送,让人们所诟病.很多消费者因为这个原因,不再考虑小米手机,尽管小米手机确实很便宜. 下面就说一下如何关闭所有的MIUI 8的广告推送.方法源自MI ...

  7. 数据同步到redis中时候需要 需要给关联的表增加id 如果是一对多 则增加list存储id 如果是一个 则增加一个字段 ;目的是便于取值

  8. Nginx Tcp四层反向代理

    L:117 //nginx反向代理代码 server{ listen ; proxy_pass localhost:; //指向上游服务器 proxy_protocol on; //启用对上游传递协议 ...

  9. 洛谷 P3953 逛公园

    题目链接 思路 首先没有0边,且k为0的情况就是最短路计数. 如果k不为0,看到k<=50,想到dp. 设f[u][i]表示到达u点比最短路多走i的路径数,转移到v点. f[u][i]+=f[v ...

  10. I - Tunnel Warfare HDU - 1540 线段树最大连续区间

    题意  :一段区间  操作1 切断点 操作2 恢复最近切断的一个点 操作3 单点查询该点所在最大连续区间 思路:  主要是push_up :  设区间x 为母区间  x<<1 ,x< ...