求一个字符串的∑ ∑ len[i] + len[j] - 2 * lcp(i, j),其中i,j表示从i,j开始的后缀。

方法一:SA+单调栈,自行yy。

方法二:SAM构造出来,然后每个状态对答案的贡献就是:C(|right_s|,2)*(Max_s-Max_parent_s)。前面使用的变量名含义与CLJ论文里的一致。right集合的大小需要构造后缀树然后从那些叶子节点开始算。

由于可以用马拉车在O(N)时间内枚举所有的回文串,所以在parent树中倍增找到每个回文串的出现次数即可。

跑得巨慢。

 #include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
//#include<iostream>
using namespace std; int n;
#define maxn 600011
char s[maxn]; struct samnode
{
int ch[],pre;
int pos;
samnode() {memset(ch,,sizeof(ch)); pre=;}
};
int pp[maxn],val[maxn];
struct SAM
{
samnode a[maxn];
int root,last,size;
SAM() {root=; a[].pos=; size=; last=root;}
int idx(char c) {return c-'a';}
void insert(char c,int p)
{
int id=idx(c),x=++size;
a[x].pos=p; pp[p]=x; val[x]=;
int y=last;
for (;y && !a[y].ch[id];y=a[y].pre) a[y].ch[id]=x;
last=x;
if (!y) a[x].pre=root;
else if (a[a[y].ch[id]].pos==a[y].pos+) a[x].pre=a[y].ch[id];
else
{
int z=a[y].ch[id],w=++size;
a[w]=a[z]; a[w].pos=a[y].pos+;
a[z].pre=a[x].pre=w;
for (;y && a[y].ch[id]==z;y=a[y].pre) a[y].ch[id]=w;
}
}
}sam; int list[maxn],fa[maxn][];
bool cmp(const int &i,const int &j) {return sam.a[i].pos>sam.a[j].pos;}
void build()
{
for (int i=;i<=sam.size;i++) list[i]=i,fa[i][]=sam.a[i].pre;
sort(list+,list++sam.size,cmp);
for (int j=;j<=;j++)
for (int i=;i<=sam.size;i++)
fa[i][j]=fa[fa[i][j-]][j-];
for (int i=;i<=sam.size;i++)
val[fa[list[i]][]]+=val[list[i]];
} #define LL long long
LL getans(int x,int len)
{
int p=pp[x];
for (int j=;j>=;j--) if (fa[p][j] && sam.a[fa[p][j]].pos>=len) p=fa[p][j];
// cout<<x<<' '<<len<<' '<<val[p]<<endl;
return 1ll*len*val[p];
} int mnc[maxn];
int main()
{
scanf("%s",s+);n=strlen(s+);
for (int i=;i<=n;i++) sam.insert(s[i],i);
build(); for (int i=n;i>=;i--)
{
s[(i<<)-]=s[i];
s[i<<]='#';
}
n=n+n-;
// cout<<s+1<<endl;
int id=;LL ans=;
for (int i=;i<=n;i++)
{
if (mnc[id]+id>i) mnc[i]=min(mnc[id*-i],mnc[id]+id-i);
else
{
mnc[i]=;
if (s[i]!='#') ans=max(ans,getans((i+)>>,));
}
while (i+mnc[i]<=n && i-mnc[i]> && s[i+mnc[i]]==s[i-mnc[i]])
{
if (s[i+mnc[i]]!='#') ans=max(ans,getans((i+mnc[i]+)>>,mnc[i]+));
mnc[i]++;
}
if (mnc[id]+id<mnc[i]+i) id=i;
// cout<<i<<' '<<mnc[i]<<endl;
}
printf("%lld\n",ans);
return ;
}

方法三:PAM。不会。

BZOJ3238:[AHOI 2013]差异的更多相关文章

  1. [BZOJ 3238] [AHOI 2013] 差异 【后缀数组 + 单调栈】

    题目链接:BZOJ - 3238 题目分析 显然,这道题就是求任意两个后缀之间的LCP的和,这与后缀数组的联系十分明显. 求出后缀数组后,求出字典序相邻两个后缀的LCP,即 Height 数组. 那么 ...

  2. [AHOI 2013]差异

    Description 题库链接 给定一个长度为 \(n\) 的字符串 \(S\) ,令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \[\sum_{1\leqslant i< ...

  3. 【BZOJ3238】[AHOI2013]差异

    [BZOJ3238][AHOI2013]差异 题面 给定字符串\(S\),令\(T_i\)表示以它从第\(i\)个字符开始的后缀.求 \[ \sum_{1\leq i<j\leq n}len(T ...

  4. 【BZOJ3238】[Ahoi2013]差异 后缀数组+单调栈

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

  5. BZOJ 3236 AHOI 2013 作业 莫队+树状数组

    BZOJ 3236 AHOI 2013 作业 内存限制:512 MiB 时间限制:10000 ms 标准输入输出     题目类型:传统 评测方式:文本比较 题目大意: 此时己是凌晨两点,刚刚做了Co ...

  6. 【BZOJ 3238】【AHOI 2013】差异

    http://www.lydsy.com/JudgeOnline/problem.php?id=3238 后缀数组裸题但是\(5\times 10^5\)貌似常数有点大就过不了?(我的sa常数那么大想 ...

  7. 【AHOI 2013】差异

    Problem Description 给定一个长度为 \(n\) 的字符串 \(S\),令 \(T_i\) 表示它从第 \(i\) 个字符开始的后缀.求 \(\sum_{1\leqslant i&l ...

  8. 【bzoj3238】 Ahoi2013—差异

    http://www.lydsy.com/JudgeOnline/problem.php?id=3238 (题目链接) 题意 给出一个字符串,求${\sum_{1<=i<j<=n} ...

  9. BZOJ 3236 AHOI 2013 作业 莫队算法

    题目大意:给出一些数,问在一个区间中不同的数值有多少种,和在一个区间中不同的数值有多少个. 思路:因为没有改动,所以就想到了莫队算法.然后我写了5K+的曼哈顿距离最小生成树,然后果断T了.(100s的 ...

随机推荐

  1. [Swift]Array数组的swapAt函数

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  2. Akka源码分析-Cluster-ClusterClient

    ClusterClient可以与某个集群通信,而本身节点不必是集群的一部分.它只需要知道一个或多个节点的位置作为联系节点.它会跟ClusterReceptionist 建立连接,来跟集群中的特定节点发 ...

  3. laravel 模型 $table $guarded $hidden

     首先以App\User模型为例 1.$table属性 表名,对应数据库中的表名 2.guarded)属性 guarded表示在create()方法中不能被赋值的字段 3.$hidden属性 $hid ...

  4. 400 Nth Digit 第N个数字

    在无限的整数序列 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...中找到第 n 个数字.注意:n 是正数且在32为整形范围内 ( n < 231).示例 1:输入:3 ...

  5. Debug技巧(1)

    首先声明,以下有些是自己遇到的问题自己解决了,其它里面包括了网上看到的Debug经验和书里看到的经验,时间问题就不一一说明,如有侵权,私信我进行删除,我会道歉.我写这个的本意是记录我学习中遇到的问题, ...

  6. python与arduino串口通讯对接opencv实现智能物品分拣

    2018-05-0118:53:50 先上图: 再来视频: http://v.youku.com/v_show/id_XMzU3NzAwNzMyNA==.html?spm=a2hzp.8244740. ...

  7. Lazarus 字符集转换 Utf8ToAnsi,UTF8ToWinCP,UTF8ToSys,UTF8ToConsole

    由于Lazarus从1.2版开始默认字符集就是UTF8,如果要转到系统正常显示或文本保存,就必须对字符集进行转换.Lazarus提供了很多函数.如题. 那么这里面有什么关系呢? UTF8ToSys 需 ...

  8. Linux系统的启动流程

    Linux系统的启动流程: 1.通电(通常按下电源键,开始通电) 2.加载BIOS (通常看到显示器提示按F2进入主板) 3.读取MBR (MBR硬盘的入口地址,用来装载引导) 4.进入引导 (通常有 ...

  9. Functions of the call stack

    https://en.wikipedia.org/wiki/Call_stack#STACK-FRAME As noted above, the primary purpose of a call s ...

  10. Python之字符串的特性及常用方法

    字符串的特性 索引: (索引是从0开始) s='hello'print(s[0])print(s[4])print(s[-1]) #拿出最后一个字符 hoo12345678截取s[start:stop ...