果然SA比SAM+map快。

首先这是SAM裸题,然而SA求本质不同子串个数也很容易。考虑倒着建SA,这样没错加一个字符就变成加一个后缀,其他后缀都不变,那么i的答案就是只考虑前i个后缀的答案。搞个双向链表,每次删一个后缀并RMQ更新答案。

(SAM+map复杂度可能是错的,但是我不清楚)

#include<algorithm>
#include<cstdio>
#define lb lower_bound
using namespace std;
const int N=1e5+5;
typedef int arr[N];
arr sa,r,f[17],c,v,s,t,p,q;
typedef long long ll;
ll b,z[N];
void pre(int*s,int n){
for(int i=0;i<n;++i)
++c[s[i]];
for(int i=1;i<n;++i)
c[i]+=c[i-1];
for(int i=n-1;~i;--i)
sa[--c[s[i]]]=i;
int m=0;
for(int i=1;i<n;++i)
r[sa[i]]=s[sa[i]]!=s[sa[i-1]]?++m:m;
for(int j=1;;j<<=1){
if(++m==n)break;
for(int i=0;i<j;++i)
v[i]=n-j+i;
for(int i=0;i<m;++i)
c[i]=0;
for(int i=0,k=j;i<n;++i){
if(sa[i]>=j)
v[k++]=sa[i]-j;
++c[r[i]];
}
for(int i=1;i<m;++i)
c[i]+=c[i-1];
for(int i=n-1;~i;--i)
sa[--c[r[v[i]]]]=v[i],v[i]=r[i];
m=r[sa[0]]=0;
for(int i=1;i<n;++i)
r[sa[i]]=v[sa[i]]!=v[sa[i-1]]||v[sa[i]+j]!=v[sa[i-1]+j]?++m:m;
}
}
int ask(int i,int j){
int k=__lg(j-i+1);
return min(f[k][i],f[k][j-(1<<k)+1]);
}
struct buf{
char z[9<<17],*s;
buf():s(z){
z[fread(z,1,sizeof z,stdin)]=0;
}
operator int(){
int x=0;
while(*s<48)++s;
while(*s>32)
x=x*10+*s++-48;
return x;
}
}it;
int main(){
int n=it;
for(int i=n-1;~i;--i)
s[i]=t[i]=it;
sort(t,t+n);
for(int i=0;i<n;++i)
s[i]=lb(t,t+n,s[i])-t+1;
pre(s,n+1);
for(int i=0,j=0;i<n;++i){
if(j)--j;
while(s[i+j]==s[sa[r[i]-1]+j])++j;
f[0][r[i]]=j;
}
for(int j=1;n>>j;++j)
for(int i=0;i+(1<<j)-1<=n;++i)
f[j][i]=min(f[j-1][i],f[j-1][i+(1<<j-1)]);
for(int i=1;i<=n;++i)
b+=n-sa[i]-f[0][i];
for(int i=n;i>1;--i)
p[i]=i-1;
for(int i=1;i<n;++i)
q[i]=i+1;
for(int i=0;i<n;++i){
int j=r[i],k=0;
if(p[j])k=max(k,ask(p[j]+1,j));
if(q[j])k=max(k,ask(j+1,q[j]));
z[i]=b,b-=n-i-k;
p[q[j]]=p[j];
q[p[j]]=q[j];
}
for(int i=n-1;~i;--i)
printf("%lld\n",z[i]);
}

BZOJ4516: [Sdoi2016]生成魔咒的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  9. BZOJ4516 SDOI2016生成魔咒(后缀自动机)

    本质不同子串数量等于所有点的len-parent树上父亲的len的和.可以直接维护. #include<iostream> #include<cstdio> #include& ...

随机推荐

  1. ViewPager 重新加载 及 PagerAdapter 使用

    PagerAdapter 简介 PagerAdapter是android.support.v4包中的类,它的子类有FragmentPagerAdapter, FragmentStatePagerAda ...

  2. Oracle工具类-生成数据库现有Job的创建脚本

    生成Oracle数据库现有Job的创建脚本 -- 生成现有Job的创建脚本 create or replace procedure proc_generate_job_create_sql is be ...

  3. SQL Server 进阶 01 数据库的设计

    SQL Server 进阶 01 数据库的设计 本篇目录 课程内容回顾及介绍 为什么需要规范的数据库设计 设计数据库的步骤 绘制E-R(实体-关系)图 实体-关系模型 如何将E-R图转换为表 数据规范 ...

  4. 转载 c# 颜色对照表

    这篇文章来来源于C# Color Table,这里是我翻译的中文版本,其中已经加上了我的一些理解和注释.翻译这篇文章的原因是我在写C#程序的时候发现,C#自带的颜色种类极多(详见下表),如果没有直观的 ...

  5. php Zend Opcache,xcache,eAccelerator缓存优化详解(具体根据个人需要选择其一即可,功能都一样切勿重复选择)

    载入 XCache 模块 引用 ;; 安装成 zend extension (推荐), 路径一般是 "$extension_dir/xcache.so" zend_extensio ...

  6. JavaScript (If...Else和Switch和循环遍历) 语句以及常用消息框

    If...Else 语句 JavaScript中if...else语句和Java中的语法和使用方法是一样的. 只是在JavaScript中要使用小写字母.使用大写的 IF 会出错! 至于if...el ...

  7. ajaxFileUpload插件

    关键词: $.ajaxFileUpLoad(); data status dataType 参考资料: http://www.cnblogs.com/kissdodog/archive/2012/12 ...

  8. MySQL 导入数据

    MySQL中可以使用两种简单的方式来导入MySQL导出的数据. 使用 LOAD DATA 导入数据 MySQL 中提供了LOAD DATA INFILE语句来插入数据. 以下实例中将从当前目录中读取文 ...

  9. jenkins / ant / jmeter 持续集成接口自动化

    1. 将 jmeter 脚本放在/var/lib/jenkins/workspace/Jmeter_auto/jmxpath路径下 2. 点击http://jk.facebank.net.cn/job ...

  10. 【repost】JavaScript 事件模型 事件处理机制

    什么是事件? 事件(Event)是JavaScript应用跳动的心脏 ,也是把所有东西粘在一起的胶水.当我们与浏览器中 Web 页面进行某些类型的交互时,事件就发生了.事件可能是用户在某些内容上的点击 ...