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 ...
随机推荐
- C语言程序设计100例之(8):尼科彻斯定理
例8 尼科彻斯定理 题目描述 尼科彻斯定理可以叙述为:任何一个整数的立方都可以表示成一串连续的奇数的和.需要注意的是,这些奇数一定是连续的,如:1,3,5,7,9,…. 例如,对于整数5,5*5 ...
- SpringBoot基本配置详解
SpringBoot项目有一些基本的配置,比如启动图案(banner),比如默认配置文件application.properties,以及相关的默认配置项. 示例项目代码在:https://githu ...
- 基于@Scheduled注解的Spring定时任务
1.创建spring-task.xml 在xml文件中加入命名空间 <beans xmlns="http://www.springframework.org/schema/beans& ...
- Swoole和Redis实现的并发队列处理系统
由于PHP不支持多线程,但是作为一个完善的系统,有很多操作都是需要异步完成的.为了完成这些异步操作,我们做了一个基于Redis队列任务系统. 大家知道,一个消息队列处理系统主要分为两大部分:消费者和生 ...
- nyoj 65-另一种阶乘问题 (Java 高精度)
65-另一种阶乘问题 内存限制:64MB 时间限制:3000ms 特判: No 通过数:16 提交数:18 难度:1 题目描述: 大家都知道阶乘这个概念,举个简单的例子:5!=1*2*3*4*5.现在 ...
- 06_K-近邻算法
k-近邻算法 算法介绍 定义: 如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一类别,则该样本也属于这个类别. 计算距离公式:欧式距离 (两点之间距离) 需要做标准化 ...
- Ubuntu 16.04 更改apt源
1 修改apt源配置文件,把/etc/apt/sources.list替换为以下内容: sudo gedit /etc/apt/sources.list deb http://mirrors.aliy ...
- IDEA+SpringBoot+Mybatis+maven分布式项目框架的搭建
参考文章:https://blog.csdn.net/qq_34410726/article/details/98214992 一.maven分布式工程的基本架构 demo #父工程模块,主要用来定 ...
- 推荐算法之用矩阵分解做协调过滤——LFM模型
隐语义模型(Latent factor model,以下简称LFM),是推荐系统领域上广泛使用的算法.它将矩阵分解应用于推荐算法推到了新的高度,在推荐算法历史上留下了光辉灿烂的一笔.本文将对 LFM ...
- Linux root设置初始值的方法
Linux root设置初始值的方法 ubuntu默认不允许使用root登录,因此初始root账户是不能使用的,需要在普通账户下利用sudo权限修改root密码. 在终端输入sudo passwd r ...