gym101431B
以此纪念我都快忘了的后缀自动机(捂脸)
不过这题有两种做法:
用后缀自动机,先把原串再接遍中间加入特殊连接字符再把原串反接两遍,对这个新构造出的串做后缀自动机。(或者直接建立广义后缀自动机)
下面只要统计长度小于等于 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的更多相关文章
随机推荐
- TC规则
633人阅读 TC规则涉及到 队列(QUEUE) 分类器(CLASS) 过滤器(FILTER),filter划分的标志位可用U32或iptables的set-mark来实现 ) 一般是" ...
- 怎么查看ubuntu是32bit还是64bit的?
怎么查看ubuntu是32bit还是64bit的?你用uname -a的时候看到的i686就是32bit的----
- Java基础之equals() 和 hashCode()
equals()是Object中的一个方法: public boolean equals(Object obj) { return (this == obj); } 在Object中equals()方 ...
- HTML标签marquee 来制作页面滚动
页面的自动滚动效果,可由javascript来实现,但是今天无意中发现了一个html标签 - <marquee></marquee>可以实现多种滚动效果,无需js控制. 使用m ...
- eclipse中修改svn用户名和密码
开发中有时候用公共的电脑提交一些代码,eclipse没有专门的切换svn账户的功能.查阅资料得出解决办法: 1. 查看你的Eclipse 中使用的是什么SVN Interface windows & ...
- Linux高级编程--01.vi命令
VI是Linux/Unix下标配的一个纯字符界面的文本编辑器.由于不支持鼠标功能,也没有图形界面,相关的操作都要通过键盘指令来完成,需要记忆大量命令.因此很多人不大喜欢它,但同时由于键盘的方式往往比鼠 ...
- JVM学习二:JVM之类加载器之加载分析
前面一遍,我们对类的加载有了一个整体的认识,而这一节我们细节分析一下类加载器的第一步,即:加载. 一.概念 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区 ...
- 【BZOJ】2440: [中山市选2011]完全平方数
[题意]T次询问第k小的非完全平方数倍数的数.T<=50,k<=10^9.(即无平方因子数——素因数指数皆为0或1的数) [算法]数论(莫比乌斯函数) [题解]考虑二分,转化为询问[1,x ...
- img图片居中
关键词:clear: both; display: block; margin:auto; 图片居左,居右,居中: /* Alignment */ .alignleft { display ...
- HDU 1711 Number Sequence (字符串处理 KMP)
题目链接 Problem Description Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...