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

不过这题有两种做法:

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

下面只要统计长度小于等于 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. 【数据结构】【平衡树】treap

    之前写treap的传送门 之前写的那个太毒瘤了,这次放一个更毒瘤的指针版上来 #include<cstdio> #include<iostream> #define rg re ...

  2. Virtual Box虚拟机下CentOS网络设置

    VirtualBox中有4中网络连接方式: a. NAT                          网络地址转换模式(Network Address Translation)b. Bridge ...

  3. ios错误码:NSError对象.code

    1. URL Loading System Error Codes These values are returned as the error code property of an NSError ...

  4. Android_UiAutomator(安卓UI自动化)环境搭建

    一.配置JDK环境变量 1.新建系统变量JAVA_HOME,然后输入引号内的内容(JDK安装目录) "C:\Program Files\Java\jdk1.8.0_51"      ...

  5. python 获取外网地址

    def get_ip(): try: url = "http://cn.bing.com/search?q=ip&go=%E6%8F%90%E4%BA%A4&qs=n& ...

  6. js实现数组排序

    1. JavaScript的sort()方法 var array = [1,4,-8,-3,6,12,9,8]; function compare(val1,val2){ return val1-va ...

  7. synchronized的实现原理

    常见三种使用方法: 1)普通同步方法,锁是当前实例: 2)静态同步方法,锁是当前类的Class实例,Class数据存在永久代中,是该类的一个全局锁: 3)对于同步代码块,锁是synchronized括 ...

  8. 说说asp.net中的异常处理和日志追踪

    关于异常的处理想必大家都了解try{}catch(){}finally{},这里就不再讲了.通过在VS里的"调试"-"异常",在弹出的异常对话框里的Common ...

  9. [linux]codeblocks开发mysql配置

    1.在安装好mysql后,可以应该安装必要的库文件 $sudo apt-get install libmysqlclient-dev 2.将codeblocks与mysql的库文件连接起来 在code ...

  10. [acmm week12]染色(容斥定理+组合数+逆元)

    1003 染色         Time Limit: 1sec    Memory Limit:256MB Description 今天离散数学课学了有关树的知识,god_v是个喜欢画画的人,所以他 ...