P4248 [AHOI2013]差异

题目描述

给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀。求

\[\displaystyle \sum_{1\leqslant i<j\leqslant n}\text{len}(T_i)+\text{len}(T_j)-2\times\text{lcp}(T_i,T_j)
\]

其中,\(\text{len}(a)\)表示字符串 \(a\) 的长度,\(\text{lcp}(a,b)\) 表示字符串 \(a\) 和字符串 \(b\) 的最长公共前缀。

输入输出格式

输入格式:

一行,一个字符串 \(S\)。

输出格式:

一行,一个整数,表示所求值。

说明

对于 \(100\%\) 的数据,保证 \(2\leqslant n\leqslant 500000\),且均为小写字母。


思路:先用SA求出height数组,然后从最小的开始删并维护联通性,发现用可以用单调栈处理这个过程。

我人太傻一开始求错了算法迷了好久...


Code:

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
const int N=5e5+10;
int sa[N],Rank[N],tax[N],sec[N],height[N],sta[N],L[N],R[N],tot,n,m;
char s[N];
void Rsort()
{
for(int i=1;i<=m;i++) tax[i]=0;
for(int i=1;i<=n;i++) ++tax[Rank[i]];
for(int i=2;i<=m;i++) tax[i]+=tax[i-1];
for(int i=n;i;i--) sa[tax[Rank[sec[i]]]--]=sec[i];
}
bool cmp(int x,int y,int l){return sec[x]==sec[y]&&sec[x+l]==sec[y+l];}
void SuffixSort()
{
scanf("%s",s+1);n=strlen(s+1);
for(int i=1;i<=n;i++) Rank[i]=s[i]+1-'a',sec[i]=i;
m=26;Rsort();
for(int p=0,w=1;p<n;w<<=1,m=p)
{
p=0;for(int i=n-w+1;i<=n;i++) sec[++p]=i;
for(int i=1;i<=n;i++) if(sa[i]>w) sec[++p]=sa[i]-w;
Rsort();std::swap(Rank,sec);
Rank[sa[1]]=p=1;
for(int i=2;i<=n;i++) Rank[sa[i]]=cmp(sa[i],sa[i-1],w)?p:++p;
}
for(int p=0,i=1;i<=n;height[Rank[i++]-1]=p)
for(p=p?p-1:p;s[i+p]==s[sa[Rank[i]-1]+p];++p);
}
int main()
{
SuffixSort();
for(int i=1;i<n;i++)
{
while(tot&&height[sta[tot]]>=height[i]) --tot;
L[i]=sta[tot]+1;
sta[++tot]=i;
}
sta[tot=0]=n;
for(int i=n-1;i;i--)
{
while(tot&&height[sta[tot]]>height[i]) --tot;
R[i]=sta[tot]-1;
sta[++tot]=i;
}
ll ans=1ll*(n+1)*(n-1)*n/2;
for(int i=1;i<n;i++)
ans-=2ll*(R[i]-i+1)*(i-L[i]+1)*height[i];
printf("%lld\n",ans);
return 0;
}

2018.12.15

P4248 [AHOI2013]差异 解题报告的更多相关文章

  1. [BZOJ3238][Ahoi2013]差异解题报告|后缀数组

    Description 先分析一下题目,我们显然可以直接算出sigma(len[Ti]+len[Tj])的值=(n-1)*n*(n+1)/2 接着就要去算这个字符串中所有后缀的两两最长公共前缀总和 首 ...

  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]差异

    思路 SAM 后缀自动机parent树的LCA就是两个子串的最长公共后缀 现在要求LCP 所以把字符串反转一下 然后每个点的贡献就是endpos的大小,dfs一遍求出贡献就可以了 代码 #includ ...

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

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

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

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

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

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

  8. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  9. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

随机推荐

  1. java-POI处理excel文件方法

    处理excel文件的开源库有很多,常见的POI.jxls..... 重点分析下POI处理excel的方法: 1.写文件 // 按照行优先进行数据表格的初始化 public static void cr ...

  2. Visual Studio的框选代码区块功能

    要从Visual Studio里复制代码粘贴到其他地方,会因为对齐的问题,造成粘贴的时候,代码左边带有大量的空格. 而VS有一个很好的功能就是框选功能,使用方法是,将光标放置在要框选代码的最左边,然后 ...

  3. Netty源码分析第8章(高性能工具类FastThreadLocal和Recycler)---->第5节: 同线程回收对象

    Netty源码分析第八章: 高性能工具类FastThreadLocal和Recycler 第五节: 同线程回收对象 上一小节剖析了从recycler中获取一个对象, 这一小节分析在创建和回收是同线程的 ...

  4. Bitcoin Core P2P网络层

    目录 数据结构 节点发现和节点连接 地址管理 节点发现 节点连接 插口(Sockets)和消息 Socket线程 (net.cpp) 消息线程 ProcessMessages (net_process ...

  5. LEETCODE —— Unique Paths II [Dynamic Programming]

    唯一路径问题II Unique Paths II Follow up for "Unique Paths": Now consider if some obstacles are ...

  6. AJAX(Asynchronous JavaScript and XML)学习笔记

    基本概念: 1.AJAX不是一种新的编程语言,而是一种使用现有标准的新方法. 2.AJAX最大的优点是在不重新加载整个页面的情况下,与服务器交换数据并更新部分网页内容,用于创建快速动态网页(传统网页如 ...

  7. 互评Beta版本——二次元梦之队——“I Do”

    基于NABCD评论作品,及改进建议 1.根据(不限于)NABCD评论作品的选题 (1)N(Need,需求) 这是一款可以教学新手入门编程的软件,不断的通关让他们慢慢学会编程,可以让没有接触过编程的人了 ...

  8. Daily Scrumming* 2015.11.2(Day 14)

    一.今明两天任务表 Member Today’s Task Tomorrow’s Task 江昊 实现前后端整合 继续实现前后端整合 杨墨犁 修改好首页 开始实现社团页 付帅 测试api 继续测试并完 ...

  9. 跟踪调试Linux内核的启动过程

    跟踪调试Linux内核的启动过程---使用gdb 符钰婧 原创作品转载请注明出处 <Linux内核分析>MOOC课程http://mooc.study.163.com/course/UST ...

  10. Ubuntu16.04下 编译安装 Tensorflow

    安装bazel sudo ./bazel***.sh 输入bazel version 检查是否安装. 编译tensorflow 1)./configure 除了选择支持cuda是y,其余的都选择n. ...