思路

SAM

后缀自动机parent树的LCA就是两个子串的最长公共后缀

现在要求LCP

所以把字符串反转一下

然后每个点的贡献就是endpos的大小,dfs一遍求出贡献就可以了

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
using namespace std;
const int MAXN = 500500*2;
int Nodecnt,trans[MAXN][26],suflink[MAXN],endpos[MAXN],maxlen[MAXN],fir[MAXN],nxt[MAXN],v[MAXN],cnt,ans,n;
char s[MAXN];
int sum(int l,int r){
if(r<l)
return 0;
return (r+l)*(r-l+1)/2;
}
void addedge(int ui,int vi){
++cnt;
v[cnt]=vi;
nxt[cnt]=fir[ui];
fir[ui]=cnt;
}
int New_state(int _maxlen,int *_trans,int _suflink){
int o=++Nodecnt;
maxlen[o]=_maxlen;
suflink[o]=_suflink;
if(_trans){
for(int i=0;i<26;i++)
trans[o][i]=_trans[i];
}
return o;
}
int add_len(int u,int c){
int z=New_state(maxlen[u]+1,NULL,0);
endpos[z]=1;
while(u&&(trans[u][c]==0)){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
return z;
}
int v=trans[u][c];
if(maxlen[u]+1==maxlen[v]){
suflink[z]=v;
return z;
}
int y=New_state(maxlen[u]+1,trans[v],suflink[v]);
suflink[z]=suflink[v]=y;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
return z;
}
void dfs(int x){
for(int i=fir[x];i;i=nxt[i]){
dfs(v[i]);
ans-=endpos[v[i]]*endpos[x]*maxlen[x]*2;
endpos[x]+=endpos[v[i]];
}
}
signed main(){
scanf("%s",s+1);
n=strlen(s+1);
reverse(s+1,s+n+1);
Nodecnt=1;
int last=1;
for(int i=1;i<=n;i++)
last=add_len(last,s[i]-'a');
for(int i=1;i<=n;i++){
int j=i+1;
ans+=(n-i+1)*(n-j+1)+sum(1,n-j+1);
}
for(int i=2;i<=Nodecnt;i++)
addedge(suflink[i],i);
dfs(1);
printf("%lld\n",ans);
return 0;
}

P4248 [AHOI2013]差异的更多相关文章

  1. P4248 [AHOI2013]差异 解题报告

    P4248 [AHOI2013]差异 题目描述 给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \[\displaystyle \s ...

  2. luogu P4248 [AHOI2013]差异 SAM

    luogu P4248 [AHOI2013]差异 链接 luogu 思路 \(\sum\limits_{1<=i<j<=n}{{len}(T_i)+{len}(T_j)-2*{lcp ...

  3. Luogu P4248 [AHOI2013]差异

    题目链接 \(Click\) \(Here\) 神仙题.或者可能我太菜了没见过后缀数组的骚操作,然后就被秀了一脸\(hhhhh\) \[\sum\limits_{1<=i < j < ...

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

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

  5. [洛谷P4248][AHOI2013]差异

    题目大意:给一个长度为$n$的字符串,求: $$\sum\limits_{1\leqslant i<j\leqslant n}|suf_i|+|suf_j|-2\times lcp(suf_i, ...

  6. BZOJ 3238: [Ahoi2013]差异 [后缀数组 单调栈]

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

  7. bzoj 3238 Ahoi2013 差异

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

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

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

  9. BZOJ_3238_[Ahoi2013]差异_后缀自动机

    BZOJ_3238_[Ahoi2013]差异_后缀自动机 Description Input 一行,一个字符串S Output 一行,一个整数,表示所求值 Sample Input cacao Sam ...

随机推荐

  1. thinkphp5中使用PHPExcel(转载)

    thinkphp5中可以使用composer来获取第三方类库,使用起来特别方便,例如:可是使用composer下载PHPMailer,think-captcha(验证码)等等…… 接下来说一下怎么使用 ...

  2. 【C++/函数】实验2

    1.实验内容 函数声明和函数定义: 形参和实参: 主调函数把实参的值传送给被调函数的形参从而实现主调函数向被调函数的数据传送. 形参:形式参数,表示主调函数与被调函数之间的联系.标识了在形参出现的位置 ...

  3. day16 十六、包、循环导入、导入模块

    一.包的概念 包:一系列模块的集合体.包通过文件夹管理一系列功能相近的模块 重点:包中一定有一个专门用来管理包中所有模块的文件 包名:存放一系列模块的文件夹的名字 包名(对象)存放的是管理模块的那个文 ...

  4. 学习 ASP.NET Core 2.1:集成测试中使用 WebApplicationFactory

    WebApplicationFactory 是 ASP.NET Core 2.1 新特性 MVC functional test infrastructure 中带来的新东东,它封装了 TestSer ...

  5. Codeforces 1100 - A/B/C/D/E/F - (Undone)

    链接:https://codeforces.com/contest/1100 A - Roman and Browser - [暴力枚举] 题意:浏览器有 $n$ 个网页,编号 $1 \sim n$, ...

  6. node_modules文件过长无法删除问题记录

    执行指令 rimraf node_modules

  7. HashMap出现Hash DOS攻击的问题

    随着RESTful风格的接口普及,程序员默认都会使用json作为数据传递的方式.json格式的数据冗余少,兼容性高,从提出到现在已被广泛的使用,可以说成为了Web的一种标准.无论我们服务端使用什么语言 ...

  8. Elasticsearch学习笔记(四)ElasticSearch分布式机制

    一.Elasticsearch对复杂分布式机制透明的隐藏特性 1.分片机制: (1)index包含多个shard,每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处 ...

  9. jquery实现一个标签图标hover到上面的时候显示tooltip

    设计图: 解决思路:1.在thumbnailbox.js这个插件中加入tags弹出框显示的内容,一开始让这些内容display:none; 然后再用css画出来一个三角形 实现方法: 知识点:Jque ...

  10. Numpy float64和Python float是一样的

    >>> numpy.float64(5.9975).hex() # 函数用于将10进制整数转换成16进制,以字符串形式表示. '0x1.7fd70a3d70a3dp+2' >& ...