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

不过这题有两种做法:

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

下面只要统计长度小于等于 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. Codeforces Round #404 (Div. 2)A B C二分

    A. Anton and Polyhedrons time limit per test 2 seconds memory limit per test 256 megabytes input sta ...

  2. 省选模拟赛 arg

    1 arg (arg.cpp/in/out, 1s, 512MB)1.1 Description给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. ...

  3. gflag使用

    #include <gflags/gflags.h> #include <iostream> // 声明全局flag DEFINE_bool(my_bool, false, & ...

  4. mac下c++代码阅读工具

    http://note.youdao.com/noteshare?id=101a265bb9d780444b6a03ca526b887a

  5. js-之闭包的理解

    说说你对闭包的理解? 答:闭包是能够读取其它函数内部变量的函数.本质上闭包是将函数内部和函数外部连接起来的一座桥梁.由于js的链式作用域,因为函数也是对象,函数内部访问函数外部的变量就类似于子对象一级 ...

  6. CentOS下安装JDK1.8

    0.卸载旧版本 键入命令java-version,查询当前JDK版本 如果版本号不是想要的,键入rpm -qa|grep gcj 键入命令 yum -y remove (后接查询得到的版本),移除老版 ...

  7. 学大伟业 2017 国庆 Day1

    期望得分:100+100+20=220 实际得分:100+100+20=220 (好久没有期望==实际了 ,~\(≧▽≦)/~) 对于 a........a 如果 第1个a 后面出现的第1个b~z 是 ...

  8. 【CodeForces】914 H. Ember and Storm's Tree Game 动态规划+排列组合

    [题目]H. Ember and Storm's Tree Game [题意]Zsnuoの博客 [算法]动态规划+排列组合 [题解]题目本身其实并不难,但是大量干扰因素让题目显得很神秘. 参考:Zsn ...

  9. spring-boot支持websocket

    spring-boot本身对websocket提供了很好的支持,可以直接原生支持sockjs和stomp协议.百度搜了一些中文文档,虽然也能实现websocket,但是并没有直接使用spring-bo ...

  10. 如何写出优雅的js以及js特殊技巧

    由于代码和解释都写在了github的readme内部,这里就直接附上github:https://github.com/jiangzhenfei/pretty-js/tree/master