https://www.lydsy.com/JudgeOnline/problem.php?id=4516

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

SAM傻逼题,然而我把SAM忘光了?

没关系SAM怎么建我还记得,咦SAM怎么统计不同字符串个数来着?

于是我看了一眼BZOJ3998:[TJOI2015]弦论

我们知道只要遍历后缀自动机就能得到所有不相同的子串,相当于每个节点有价值size=1,如果我们倒序遍历并且累加的话就能求出sum。

当然我们没必要每次都求一遍sum,我们发现我们新加入的节点,其造成的贡献按照我们上面的推论就是tr[np].l-tr[tr[np].fa].l。

(你可以试着画一个简单的后缀自动机感受一下,比如说“1231”,你就会发现实际造成贡献的就是fa~np的每个节点(除np)都由np转移来了+1,这些1需要累加到一起汇总到root,当然同理对于我们因为right集合不同而新开的点也是一样的。)

没了,很水吧。

#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
#define fi first
#define se second
const int N=1e5+;
inline int read(){
int X=,w=;char ch=;
while(!isdigit(ch)){w|=ch=='-';ch=getchar();}
while(isdigit(ch))X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
map<int,int>::iterator it;
struct node{
map<int,int>a;
int fa,l;
}tr[N<<];
int n,last,cnt;
ll ans;
inline void insert(int c){
int p=last,np=++cnt;
last=np;tr[np].l=tr[p].l+;
for(;p&&!tr[p].a[c];p=tr[p].fa)tr[p].a[c]=np;
if(!p)tr[np].fa=;
else{
int q=tr[p].a[c];
if(tr[p].l+==tr[q].l)tr[np].fa=q;
else{
int nq=++cnt;tr[nq].l=tr[p].l+;
for(it=tr[q].a.begin();it!=tr[q].a.end();it++)
tr[nq].a[it->fi]=it->se;
tr[nq].fa=tr[q].fa;tr[q].fa=tr[np].fa=nq;
for(;tr[p].a[c]==q;p=tr[p].fa)tr[p].a[c]=nq;
}
}
ans+=tr[np].l-tr[tr[np].fa].l;
}
int main(){
n=read();
last=cnt=;
for(int i=;i<=n;i++){
insert(read());printf("%lld\n",ans);
}
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4516:[SDOI2016]生成魔咒——题解的更多相关文章

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

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

  2. BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】

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

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

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

  4. BZOJ4516 SDOI2016生成魔咒(后缀数组+平衡树)

    一个字符串本质不同的子串数量显然是总子串数减去所有height值.如果一个个往里加字符的话,每次都会改动所有后缀完全没法做.但发现如果从后往前加的话,每次只会添加一个后缀.于是我们把字符串倒过来,每次 ...

  5. bzoj4516: [Sdoi2016]生成魔咒 sam

    题意:每次插入一个数字,查询本质不同的子串有多少个 题解:sam,数字很大,ch数组用map来存,每次ins之后查询一下新建点表示多少个本质不同的子串(l[np]-l[fa[np]]) /****** ...

  6. bzoj千题计划283:bzoj4516: [Sdoi2016]生成魔咒(后缀数组)

    http://www.lydsy.com/JudgeOnline/problem.php?id=4516 考虑在后面新加一个字母产生的影响 假设是第i个 如果不考虑重复,那么会增加i个不同的字符串 考 ...

  7. BZOJ4516: [Sdoi2016]生成魔咒

    果然SA比SAM+map快~加了fread目前rank1. 首先这是SAM裸题,然而SA求本质不同子串个数也很容易.考虑倒着建SA,这样没错加一个字符就变成加一个后缀,其他后缀都不变,那么i的答案就是 ...

  8. 2018.12.23 bzoj4516: [Sdoi2016]生成魔咒(后缀自动机)

    传送门 samsamsam入门题. 题意简述:给出一个串让你依次插入字符,求每次插入字符之后不同子串的数量. 显然每次的变化量只跟新出现的nnn个后缀有关系,那么显然就是maxlenp−maxlenl ...

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

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

随机推荐

  1. IAR环境下编译CC2640入门开发

    1. 安装SDK包,之后导入AIR里面,编译报错 看样子似乎是xdc工具的路径配置不对,进入路径配置对话窗 开始配置 配置完之后,重新编译 Fatal Error[Pe1696]: cannot op ...

  2. SpringBoot学习:整合shiro(验证码功能和登录次数限制功能)

    项目下载地址:http://download.csdn.NET/detail/aqsunkai/9805821 (一)验证码 首先login.jsp里增加了获取验证码图片的标签: <body s ...

  3. mysql 优化笔记

    数据表总共81万条数 SQL explain ); 执行时间超级长,没有等到执行完成就终止了太慢了 explain一下 发现表bb 的select_type 为DEPENDENT SUBQUERY   ...

  4. Oracle锁表处理

    最近系统连续出现好几次锁表,昨晚又发生一次锁表,11点钟跑到客户现场,进过跟踪发现导致这次锁表的机器和上一次是同一台,花了近半小时解锁.之后到科室找到那台机器看看情况,发现那台机器速度超慢,保存一份病 ...

  5. ReadyAPI教程和示例(一)

    声明:如果你想转载,请标明本篇博客的链接,请多多尊重原创,谢谢! 本篇使用的 ReadyAPI版本是2.5.0 通过下图你可以快速浏览一下主要的ReadyAPI中SoapUI功能: ​ 一.创建一个功 ...

  6. Python文件操作大全

    Python 编程文件操作大全   文件打开模式 打开模式 执行操作 'r' 以只读方式打开文件(默认) 'w' 以写入的方式打开文件,会覆盖已存在的文件 'x' 如果文件已经存在,使用此模式打开将引 ...

  7. 树(Tree,UVA 548)

    题目描述: 题目思路: 1.使用数组建树 //递归 2.理解后序遍历和中序遍历,建立左右子树 3.dfs深度搜索找出权重最小的路径 #include <iostream> #include ...

  8. 子序列 (All in All,UVa10340)

    题目描述:算法竞赛入门经典习题3-9 题目思路:循环匹配 //没有按照原题的输入输出 #include <stdio.h> #include <string.h> #defin ...

  9. ElasticSearch 论坛搜索查询语句

    概述 研究论坛搜索如何综合时间和TF/IDF权重. 自定义权重计算的效率问题 数据结构 假设有一个论坛的搜索 字段包括: subject:标题 message:内容 dateline:发布时间 tag ...

  10. anaconda安装scrapy报错解决办法

    今天在用anaconda安装scrapy的时候遇见个坑,现在将解决办法发出来,供大家参考使用: 问题描述: anaconda安装scrapy,使用 conda install scrapy 命令.安装 ...