洛谷P4070 生成魔咒
题意:给定字符串,求每个前缀的本质不同的子串数量。字符集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 生成魔咒的更多相关文章
- 洛谷 P4070 [SDOI2016]生成魔咒 解题报告
P4070 [SDOI2016]生成魔咒 题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 \(1\).\(2\) 拼凑起来形成一个魔咒串 \([1,2]\). 一个魔咒 ...
- P4070 [SDOI2016]生成魔咒
题目地址:P4070 [SDOI2016]生成魔咒 相信看到题目之后很多人跟我的思路是一样的-- 肯定要用 SA(P3809 [模板]后缀排序) 肯定要会求本质不同的子串个数(P2408 不同子串个数 ...
- bzoj4516 / P4070 [SDOI2016]生成魔咒
P4070 [SDOI2016]生成魔咒 后缀自动机 每插入一个字符,对答案的贡献为$len[last]-len[fa[last]]$ 插入字符范围过大,所以使用$map$存储. (去掉第35行就是裸 ...
- 【LG4070】[SDOI2016]生成魔咒
[LG4070][SDOI2016]生成魔咒 题面 洛谷 题解 如果我们不用在线输的话,那么答案就是对于所有状态\(i\) \[ \sum (i.len-i.fa.len) \] 现在我们需要在线询问 ...
- BZOJ4516: [Sdoi2016]生成魔咒 后缀自动机
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...
- BZOJ 4516: [Sdoi2016]生成魔咒 [后缀自动机]
4516: [Sdoi2016]生成魔咒 题意:询问一个字符串每个前缀有多少不同的子串 做了一下SDOI2016R1D2,题好水啊随便AK 强行开map上SAM 每个状态的贡献就是\(Max(s)-M ...
- [SDOI2016]生成魔咒
题目描述 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1, ...
- BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay
BZOJ_4516_[Sdoi2016]生成魔咒_后缀数组+ST表+splay Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔 ...
- [BZOJ 4516] [SDOI 2016] 生成魔咒
Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例 ...
随机推荐
- 50分钟学会Laravel 50个小技巧(基于laravel5.2,仅供参考)
转载请注明:转载自 Yuansir-web菜鸟 | LAMP学习笔记 本文链接地址: 50分钟学会Laravel 50个小技巧 原文链接:< 50 Laravel Tricks in 50 Mi ...
- 转《service worker在移动端H5项目的应用》
1. PWA和Service Worker的关系 PWA (Progressive Web Apps) 不是一项技术,也不是一个框架,我们可以把她理解为一种模式,一种通过应用一些技术将 Web App ...
- Excel文件读取的两种方式
1.Pandas库的读取操作 from pandas import read_excel dr=read_excel(filename,header) dr#dataframe数据 dw=DataFr ...
- JavaScript中forEach与each
forEach是ES5中操作数组的一种方法,主要功能是遍历数组,例如: var arr = [1,2,3,4]; arr.forEach(alert); 等价于: var arr = [1, 2, 3 ...
- vue-cli: render:h => h(App)是什么意思
import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false new Vue({ render: ...
- Lodop打印控件指定打印任务某几页
使用Lodop打印控件进行打印开发,有时候一个任务里有多页,例如各种合同之类的,客户端用户在使用过程中,可能有某一页打印后发现需要修改,这时候不必再把整个任务重新打印一遍,只需要打印需要修改的那页重新 ...
- HTTP协议【详解】——经典面试题
http请求由三部分组成,分别是:请求行.消息报头.请求正文 HTTP(超文本传输协议)是一个基于请求与响应模式的.无状态的.应用层的协议,常基于TCP的连接方式,HTTP1.1版本中给出一种持续连接 ...
- JAVA spring配置文件总结
首先来看一个标准的Spring配置文件 applicationContext.xml <?xml version="1.0" encoding="UTF-8&quo ...
- BZOJ1503[NOI2004]郁闷的出纳员——treap
OIER公司是一家大型专业化软件公司,有着数以万计的员工.作为一名出纳员,我的任务之一便是统计每位员工的工资.这本来是一份不错的工作,但是令人郁闷的是,我们的老板反复无常,经常调整员工的工资.如果他心 ...
- POJ1151-扫面线+线段树+离散化//入门题
比较水的入门题 记录矩形竖边的x坐标,离散化排序.以被标记的边建树. 扫描线段树,查询线段树内被标记的边.遇到矩形的右边就删除此边 每一段的面积是查询结果乘边的横坐标之差,求和就是答案 #includ ...