以此纪念我都快忘了的后缀自动机(捂脸)

不过这题有两种做法:

用后缀自动机,先把原串再接遍中间加入特殊连接字符再把原串反接两遍,对这个新构造出的串做后缀自动机。(或者直接建立广义后缀自动机)

下面只要统计长度小于等于 n 的串即可。这可以从 parent 树即后缀树来考虑,注意到每个节点可以接收的子串长度为[mxlen[fa[x]]+1,mxlen[x]]

只要对这个长度区间对n取min再统计即可

 #include<bits/stdc++.h>

 using namespace std;
typedef long long ll;
int fa[],go[][],mx[],n,t,last;
char a[];
void add(int c)
{
int np,nq,q,p=last;
if (!go[last][c])
{
np=++t;
mx[np]=mx[p]+;
for (;p&&!go[p][c]; p=fa[p]) go[p][c]=np;
}
else np=;
if (!p) fa[np]=;
else {
q=go[p][c];
if (mx[q]==mx[p]+) fa[np]=q;
else {
nq=++t;
mx[nq]=mx[p]+;
memcpy(go[nq],go[q],sizeof(go[q]));
fa[nq]=fa[q]; fa[q]=fa[np]=nq;
for (;go[p][c]==q; p=fa[p]) go[p][c]=nq;
}
}
last=go[last][c];
} int main()
{
scanf("%d",&n);
scanf("%s",a+);
last=t=;
for (int i=; i<=n; i++)
add(a[i]-'a');
for (int i=; i<=n; i++)
add(a[i]-'a');
last=;
for (int i=n; i; i--)
add(a[i]-'a');
for (int i=n; i; i--)
add(a[i]-'a');
ll ans=;
for (int i=; i<=t; i++)
ans+=min(n,mx[i])-min(mx[fa[i]],n);
printf("%lld\n",ans);
}

自动机

另一种诡异的做法:由于数据随机,那么当串长足够大时很大概率都是互不相同的,干脆就直接认为全不相同

因此只要找小串长的不同种类即可,这就直接用 hash

暴力判断即可。

 #include<bits/stdc++.h>

 using namespace std;
typedef long long ll;
char a[];
set<ll> f[];
int n;
using namespace std;
typedef long long ll;
const int mx=;
int main()
{
scanf("%d",&n);
scanf("%s",a);
for (int i=; i<n; i++)
{
ll h1=,h2=;
for (int l=; l<min(n,mx); l++)
{
h1=h1*+a[(i+l)%n]-'a';
h2=h2*+a[(i-l+n)%n]-'a';
f[l].insert(h1);
f[l].insert(h2);
}
}
ll ans=2ll*n*max(,n-mx);
for (int l=; l<mx; l++)
ans+=f[l].size();
printf("%lld\n",ans);
}

gym101431B的更多相关文章

随机推荐

  1. 基于 Quartz.NET 实现可中断的任务

    基于 Quartz.NET 实现可中断的任务 Quartz.NET 是一个开源的作业调度框架,非常适合在平时的工作中,定时轮询数据库同步,定时邮件通知,定时处理数据等. Quartz.NET 允许开发 ...

  2. opencv查找轮廓---cvFindContours && cvDrawCountours 用法及例子

    http://blog.csdn.net/timidsmile/article/details/8519751 环境: vs2008 + opencv2.1 先看,这两个函数的用法(参考 opencv ...

  3. PID控制算法的C语言实现一 PID算法原理

    本系列是转载............. 全部的程序有一个共同点:就是我没认真去调pid的参数 在工业应用中PID及其衍生算法是应用最广泛的算法之一,是当之无愧的万能算法,如果能够熟练掌握PID算法的设 ...

  4. IO多路复用之epoll(二)

    前一篇介绍了epoll的LT模式,LT模式注意epollout事件在数据全部写成功后需要取消关注, 或者更改为EPOLLIN. 而这次epoll的ET模式,要注意的是在读和写的过程中要在循环中写完或者 ...

  5. IO多路复用之epoll(一)讲解

    网络通信中socket有自己的内核发送缓冲区和内核接受缓冲区,好比是一个水池, 当用户发送数据的时候会从用户缓冲区拷贝到socket的内核发送缓冲区,然后从 socket发送缓冲区发出去, 当用户要读 ...

  6. HashMap源码翻译

    /* * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * ORACLE PROPRIETA ...

  7. JS笔记-强化版1

    1.函数:可以理解为-命令,做一些事~~       function abc(){ // 肯定不会主动执行的!       ……       }       直接调用:abc();       事件 ...

  8. HTML不常用的表单属性-fieldset

    这是代码 这是生成的样子 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http: ...

  9. UVA 12520 Square Garden

    https://vjudge.net/problem/UVA-12520 题意:n*n网格中染色m个格子,染色格子的最长轮廓线 贪心 将格子分为4类 1.隔一个选一个,互不相邻的格子 2.4个角上的格 ...

  10. Python学习笔记(三十五)—内置模块(4)struct

    摘抄自:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001431955007 ...