2019牛客全国多校训练四 I题 string (SAM+PAM)
链接:https://ac.nowcoder.com/acm/contest/884/I
来源:牛客网
题目描述
输入描述:
A line containing a string sss of lower-case letters.
输出描述:
A positive integer - the largest possible number of substrings of sss that are non-equivalent.
输入
abac
输出
8
说明
The set of following substrings is such a choice: abac,b,a,ab,aba,bac,ac,cabac,b,a,ab,aba,bac,ac,cabac,b,a,ab,aba,bac,ac,c.
备注:
1≤∣s∣≤2×1051 \leq |s|\leq 2 \times 10^51≤∣s∣≤2×105, sss is consisted of lower-case letters.
题解:
题目给你一个字符串s,让你求s中的子串组成的最大集合,满足这个集合内的每一个子串str, str和rev(str)不同时存在{rev(str):表示str反过来}
思路:就是先用SAM统计出s#rev(s)中不包含 '#'的所有子串ans1; 然后用PAM统计出s中本质不同的子串数量ans2;
这答案就是(ans1+ans2)/2;
为什么呢?
因为在用SAM统计s#rev(s)的时候会把所有字符串统计两边,而本身就是回文串的只会统计一遍。
参考代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pii pair<int,int>
#define pil pair<int,long long>
const int INF=0x3f3f3f3f;
const ll inf=0x3f3f3f3f3f3f3f3fll;
inline int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
const int maxn=4e5+;
const int MAXN=4e5+;
char str[maxn];
int s[maxn];
ll ans;
struct SAM{
int l[maxn<<],fa[maxn<<],nxt[maxn<<][];
int last,cnt; void Init()
{
ans=;last=cnt=;
l[cnt]=fa[cnt]=;
memset(nxt[cnt],,sizeof(nxt[cnt]));
} int NewNode()
{
++cnt;
memset(nxt[cnt],,sizeof(nxt[cnt]));
l[cnt]=fa[cnt]=;
return cnt;
} void Insert(int ch)
{
int np=NewNode(),p=last;
last=np; l[np]=l[p]+;
while(p&&!nxt[p][ch]) nxt[p][ch]=np,p=fa[p];
if(!p) fa[np]=;
else
{
int q=nxt[p][ch];
if(l[p]+==l[q]) fa[np]=q;
else
{
int nq=NewNode();
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
fa[nq]=fa[q];
l[nq]=l[p]+;
fa[np]=fa[q]=nq;
while(nxt[p][ch]==q) nxt[p][ch]=nq,p=fa[p];
}
}
ans+=1ll*(l[last]-l[fa[last]]);
} }sam; struct Palindromic_Tree{
int next[MAXN][];
int fail[MAXN];
int cnt[MAXN];
int num[MAXN];
int len[MAXN];
int S[MAXN];
int last;
int n;
int p; int newnode(int l)
{
for(int i=;i<;++i) next[p][i]=;
cnt[p]=;
num[p]=;
len[p]=l;
return p++;
} void Init()
{
p=;
newnode( );
newnode(-);
last=;
n=;
S[n]=-;
fail[]=;
} int get_fail(int x)
{
while(S[n-len[x]-]!=S[n])x=fail[x] ;
return x ;
} void add(int c)
{
S[++ n]=c;
int cur=get_fail(last) ;
if(!next[cur][c])
{
int now=newnode(len[cur]+) ;
fail[now]=next[get_fail(fail[cur])][c] ;
next[cur][c]=now ;
num[now]=num[fail[now]]+;
}
last=next[cur][c];
cnt[last]++;
} ll count()
{
ll res=p*1ll;
for(int i=p-;i>=;--i) cnt[fail[i]]+=cnt[i];
//for(int i=1;i<=p;++i) res+=cnt[i];
//cout<<"res "<<res<<endl;
return (res-);
}
} pam; int main()
{
scanf("%s",str);
int len=strlen(str); sam.Init();
for(int i=;i<len;++i) sam.Insert(str[i]-'a');
sam.Insert();
for(int i=len-;i>=;--i) sam.Insert(str[i]-'a');
ans-=1ll*(len+)*(len+);
//cout<<"ans "<<ans<<endl;
pam.Init();
for(int i=;i<len;++i) pam.add(str[i]-'a');
ans=ans+pam.count(); printf("%lld\n",(ans/2ll)); return ;
}
2019牛客全国多校训练四 I题 string (SAM+PAM)的更多相关文章
- 2019牛客全国多校第八场A题 All-one Matrices(单调栈)
题意:让你找最大不可扩展全1子矩阵的数量: 题解:考虑枚举每一行为全1子矩阵的的底,然后从左到右枚举:up[i][j]:表示(i,j)这个位置向上可扩展多少,同时还有记录每个位置(i,j)向左最多可扩 ...
- 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题)
layout: post title: 2019牛客暑期多校训练营(第五场)G - subsequeue 1 (一题我真的不会的题) author: "luowentaoaa" c ...
- 2019牛客暑期多校训练营(第九场)A:Power of Fibonacci(斐波拉契幂次和)
题意:求Σfi^m%p. zoj上p是1e9+7,牛客是1e9: 对于这两个,分别有不同的做法. 前者利用公式,公式里面有sqrt(5),我们只需要二次剩余求即可. 后者mod=1e9,5才 ...
- 2019牛客暑期多校训练营(第一场)A题【单调栈】(补题)
链接:https://ac.nowcoder.com/acm/contest/881/A来源:牛客网 题目描述 Two arrays u and v each with m distinct elem ...
- 2019牛客暑期多校训练营(第一场) B Integration (数学)
链接:https://ac.nowcoder.com/acm/contest/881/B 来源:牛客网 Integration 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 5242 ...
- 2019牛客暑期多校训练营(第一场) A Equivalent Prefixes ( st 表 + 二分+分治)
链接:https://ac.nowcoder.com/acm/contest/881/A 来源:牛客网 Equivalent Prefixes 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/ ...
- 牛客网多校训练第二场D Kth Minimum Clique
链接:https://ac.nowcoder.com/acm/contest/882/D来源:牛客网 Given a vertex-weighted graph with N vertices, fi ...
- 2019牛客暑期多校训练营(第二场)F.Partition problem
链接:https://ac.nowcoder.com/acm/contest/882/F来源:牛客网 Given 2N people, you need to assign each of them ...
- 2019牛客暑期多校训练营(第八场)E.Explorer
链接:https://ac.nowcoder.com/acm/contest/888/E来源:牛客网 Gromah and LZR have entered the fifth level. Unli ...
随机推荐
- jquery鼠标点击穿透的解决方法
jquery鼠标点击穿透的解决方法 <pre><div class="showcontainer" style="background:#000;dis ...
- TCP time_wait close_wait问题(可能是全网最清楚的例子)
背景 公司群里,运维发现一个问题,task服务报错(如下) The stream or file \"/data/logs/adn_task/offer_service.log\" ...
- jenkins手把手教你从入门到放弃01-jenkins简介(详解)
一.简介 jenkins是一个可扩展的持续集成引擎.持续集成,也就是通常所说的CI(Continues Integration),可以说是现代软件技术开发的基础.持续集成是一种软件开发实践, 即团队开 ...
- 用户环境变量 shell变量 别名
常见用户环境变量: 环境变量 说明 LANG HOME LOGNAME 用户名 PATH SHELL PWD 查看环境变量用:env或者echo $LANG 设置用户环境变量:ex ...
- 附010.Kubernetes永久存储之GlusterFS超融合部署
一 前期准备 1.1 基础知识 在Kubernetes中,使用GlusterFS文件系统,操作步骤通常是: 创建brick-->创建volume-->创建PV-->创建PVC--&g ...
- 0MQ宗旨
先来看<Implementing distributed applications with 0MQ and some other bad guys...>.用0MQ去实现分布应用,或者用 ...
- Tarjan-割点
割点——tarjan #include <bits/stdc++.h> using namespace std; ; ; int n, m; int ans;//个数 * MAXM], n ...
- react一写工具
动画库:React-transition-group ui框架:Ant Design
- PHP编程20大效率要点
1.如果能将类的方法定义成static,就尽量定义成static,它的速度会提升将近4倍. 2.$row[’id’] 的速度是$row[id]的7倍. 3.echo 比 print 快,并且使用ech ...
- 超速入门AT指令集 | 我的物联网成长记
[摘要] 在物联网中,AT命令集可用于控制&调测设备.通信模块入网等.本文为您介绍NB-IoT常用的AT命令集及其调测工具. 什么是AT指令集 AT命令,用来控制TE(Terminal Equ ...