BZOJ4516:[SDOI2016]生成魔咒——题解
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]生成魔咒——题解的更多相关文章
- BZOJ4516: [Sdoi2016]生成魔咒 后缀自动机
#include<iostream> #include<cstdio> #include<cstring> #include<queue> #inclu ...
- BZOJ4516 [Sdoi2016]生成魔咒 【后缀自动机】
题目 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生成魔咒. 例如 S=[1,2, ...
- [bzoj4516][Sdoi2016]生成魔咒——后缀自动机
Brief Description 魔咒串由许多魔咒字符组成,魔咒字符可以用数字表示.例如可以将魔咒字符 1.2 拼凑起来形成一个魔咒串 [1,2]. 一个魔咒串 S 的非空字串被称为魔咒串 S 的生 ...
- BZOJ4516 SDOI2016生成魔咒(后缀数组+平衡树)
一个字符串本质不同的子串数量显然是总子串数减去所有height值.如果一个个往里加字符的话,每次都会改动所有后缀完全没法做.但发现如果从后往前加的话,每次只会添加一个后缀.于是我们把字符串倒过来,每次 ...
- bzoj4516: [Sdoi2016]生成魔咒 sam
题意:每次插入一个数字,查询本质不同的子串有多少个 题解:sam,数字很大,ch数组用map来存,每次ins之后查询一下新建点表示多少个本质不同的子串(l[np]-l[fa[np]]) /****** ...
- bzoj千题计划283:bzoj4516: [Sdoi2016]生成魔咒(后缀数组)
http://www.lydsy.com/JudgeOnline/problem.php?id=4516 考虑在后面新加一个字母产生的影响 假设是第i个 如果不考虑重复,那么会增加i个不同的字符串 考 ...
- BZOJ4516: [Sdoi2016]生成魔咒
果然SA比SAM+map快~加了fread目前rank1. 首先这是SAM裸题,然而SA求本质不同子串个数也很容易.考虑倒着建SA,这样没错加一个字符就变成加一个后缀,其他后缀都不变,那么i的答案就是 ...
- 2018.12.23 bzoj4516: [Sdoi2016]生成魔咒(后缀自动机)
传送门 samsamsam入门题. 题意简述:给出一个串让你依次插入字符,求每次插入字符之后不同子串的数量. 显然每次的变化量只跟新出现的nnn个后缀有关系,那么显然就是maxlenp−maxlenl ...
- BZOJ4516: [Sdoi2016]生成魔咒(后缀数组 set RMQ)
题意 题目链接 Sol 毒瘤SDOI 终于有一道我会做的题啦qwq 首先,本质不同的子串的个数 $ = \frac{n(n + 1)}{2} - \sum height[i]$ 把原串翻转过来,每次就 ...
随机推荐
- jquery 点滴
jQuery——动态给表格添加序号 $(function(){ //$('table tr:not(:first)').remove(); var len = $('table tr').length ...
- mysql数据库目录存放位置更改
http://haowen.blog.51cto.com/3486731/1274721 mysql数据库存储路径更改 使用了VPS一段时间之后发现磁盘空间快满了.本人的VPS在购买的时候买了500g ...
- Qt-QML-自定义个自己的文本Text
好久都没有正经的更新自己的文章了,这段时间也辞职了,听了小爱的,准备买个碗,自己当老板,下面请欣赏效果图 这个界面布局就是自己是在想不到啥了,按照常规汽车导航的布局布局了一下,主要看内容哈,看看这个文 ...
- Http的请求和响应
请求有客户端发起:可分为4个部分,请求方法(Requestmethod).请求的网址(Request URL).请求头(Request Headers).请求体(Request Body) 1.请求方 ...
- 【转】上线游戏参考数值(Unity)
转自游戏开发主席 贴图格式: iOS :RGBA 32 (pvrtc 4 ) Android : RGB Compresed ETC 4 或 RGBA 32 . DrawCall: 总计Drawca ...
- 开关灯问题(C++)
[问题描述] 假设有 N 盏灯(N 为不大于 5000 的正整数),从 1 到 N 按顺序依次编号,初始时全部处于开启状态:有 M 个人(M 为不大于 N 的正整数)也从 1 到 M 依次编号.第一个 ...
- 从Softmax回归到Logistic回归
Softmax回归是Logistic回归在多分类问题上的推广,是有监督的. 回归的假设函数(hypothesis function)为,我们将训练模型参数,使其能够最小化代价函数: 在Softmax回 ...
- vmware安装64位系统“此主机支持 Intel VT-x,但 Intel VT-x 处于禁用状态”的问题
虚拟机使用的是VMware Workstation,并且首次在虚拟机体验64 位系统.在新建好虚拟机,运行时候就出现了VMware Workstation 的提醒:此主机支持 Intel VT-x,但 ...
- window.open()与window.showModalDialog区别
window.open()与window.showModalDialog区别 弹出窗口两种方式: 1.window.showModalDialog: var feature = &qu ...
- 又见CLOSE_WAIT
原文: http://mp.weixin.qq.com/s?__biz=MzI4MjA4ODU0Ng==&mid=402163560&idx=1&sn=5269044286ce ...