传送门

后缀自动机好题。

题意:


做法:samsamsam 废话

考虑翻转字串,这样后缀的最长公共前缀等于前缀的最长公共后缀。

然后想到parentparentparent树上面两个串的最长公共后缀跟他们所处状态的lcalcalca有关系。

于是对于每一个lcalcalca都处理出它的sizesizesize和maxlengthmax_{length}maxlength​就行了。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
const int N=1e6+5;
int n;
char s[N];
struct SAM{
	int last,rt,tot,link[N],len[N],siz[N],son[N][26],rk[N],cnt[N];
	SAM(){rt=last=tot=1,len[0]=-1,fill(son[0],son[0]+26,1);}
	inline void expand(int x){
		int p=last,np=++tot;
		siz[last=np]=1,len[np]=len[p]+1;
		while(p&&!son[p][x])son[p][x]=np,p=link[p];
		if(!p){link[np]=rt;return;}
		int q=son[p][x],nq;
		if(len[q]==len[p]+1){link[np]=q;return;}
		len[nq=++tot]=len[p]+1,memcpy(son[nq],son[q],sizeof(son[q])),link[nq]=link[q];
		while(p&&son[p][x]==q)son[p][x]=nq,p=link[p];
		link[np]=link[q]=nq;
	}
	inline void topsort(){
		ll ans=(ll)(n-1)*n*(n+1)/2;
		for(ri i=1;i<=tot;++i)++cnt[len[i]];
		for(ri i=1;i<=last;++i)cnt[i]+=cnt[i-1];
		for(ri i=1;i<=tot;++i)rk[cnt[len[i]]--]=i;
		for(ri i=tot;i;--i)siz[link[rk[i]]]+=siz[rk[i]];
		for(ri i=2;i<=tot;++i)ans-=(ll)(len[i]-len[link[i]])*siz[i]*(siz[i]-1);
		cout<<ans;
	}
}sam;
int main(){
	scanf("%s",s+1),n=strlen(s+1),reverse(s+1,s+n+1);
	for(ri i=1;i<=n;++i)sam.expand(s[i]-'a');
	sam.topsort();
	return 0;
}

2018.12.21 bzoj3238: [Ahoi2013]差异(后缀自动机)的更多相关文章

  1. [bzoj3238][Ahoi2013]差异——后缀自动机

    Brief Description Algorithm Design 下面给出后缀自动机的一个性质: 两个子串的最长公共后缀,位于这两个串对应的状态在parent树上的lca状态上.并且最长公共后缀的 ...

  2. BZOJ3238: [Ahoi2013]差异(后缀自动机)

    题意 题目链接 Sol 前面的可以直接算 然后原串翻转过来,这时候变成了求任意两个前缀的最长公共后缀,显然这个值应该是\(len[lca]\),求出\(siz\)乱搞一下 #include<bi ...

  3. BZOJ 3238: [Ahoi2013]差异 [后缀自动机]

    3238: [Ahoi2013]差异 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 2512  Solved: 1140[Submit][Status ...

  4. bzoj3238 [Ahoi2013]差异 后缀数组+单调栈

    [bzoj3238][Ahoi2013]差异 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sample Ou ...

  5. [Ahoi2013]差异(后缀自动机)

    /* 前面的那一坨是可以O1计算的 后面那个显然后缀数组单调栈比较好写??? 两个后缀的lcp长度相当于他们在后缀树上的lca的深度 那么我们就能够反向用后缀自动机构造出后缀树然后统计每个点作为lca ...

  6. 2018.12.15 hdu4641 K-string(后缀自动机)

    传送门 后缀自动机基础题. 题意简述:支持动态在串尾插入字符,查询在串中出现超过kkk次的子串的个数. 动态修改samsamsam,每次增量构造好了之后在parentparentparent树上从新建 ...

  7. 2018.12.15 spoj Substrings(后缀自动机)

    传送门 后缀自动机基础题. 求长度为iii的子串出现次数的最大值. 对原串建出samsamsam,然后用sizsizsiz更新每个maxlenmaxlenmaxlen的答案. 然后由于后缀链接将其转化 ...

  8. 洛谷P4248 [AHOI2013]差异(后缀自动机求lcp之和)

    题目见此 题解:首先所有后缀都在最后一个np节点,然后他们都是从1号点出发沿一些字符边到达这个点的,所以下文称1号点为根节点,我们思考一下什么时候会产生lcp,显然是当他们从根节点开始一直跳相同节点的 ...

  9. BZOJ 3238 [Ahoi2013]差异 ——后缀自动机

    后缀自动机的parent树就是反串的后缀树. 所以只需要反向构建出后缀树,就可以乱搞了. #include <cstdio> #include <cstring> #inclu ...

随机推荐

  1. Toolbar 工具栏 菜单 标题栏 Menu

    要使用Toolbar,要先将标题栏(ActionBar)关掉: style.xml中:<style name="MainActivityTheme" parent=" ...

  2. WLC5520无法通过无线客户端进行网管故障解决

    客户反馈其办公环境中的WLC5520网管需要通过内部有线网络进行管理,通过无线客户端无法进行管理,远程协助其开启WLC5520的无线管理功能后故障解决.

  3. Round Numbers(数位DP)

    Round Numbers http://poj.org/problem?id=3252 Time Limit: 2000MS   Memory Limit: 65536K Total Submiss ...

  4. 命令行操作mysql数据库

    1.导出整个数据库mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u dbuser -p dbname > dbname.sql 2.导出一个表m ...

  5. sizeof 4字节对齐

    #include <iostream> #include<assert.h> using namespace std; typedef struct sys{ char a; ...

  6. 【Linux 进程】孤儿进程、僵尸进程和守护进程

    1.孤儿进程: 孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程.孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作.孤儿进程是 ...

  7. classLoader.getResourceAsStream中文乱码

    一直用一个方法安然无恙,今天在新项目中突然乱码了,原代码: ClassLoader classLoader = Thread.currentThread().getContextClassLoader ...

  8. Spring Cloud入门教程(二):客户端负载均衡(Ribbon)

    对于大型应用系统负载均衡(LB:Load Balancing)是首要被解决一个问题.在微服务之前LB方案主要是集中式负载均衡方案,在服务消费者和服务提供者之间又一个独立的LB,LB通常是专门的硬件,如 ...

  9. AndroidManifest中注册application

    <application android:icon="@drawable/icon1" android:label="@string/app_name" ...

  10. andorid EditView

    <?xml version="1.0" encoding="utf-8"?> <GridLayout xmlns:android=" ...