并不对劲的spoj nsubstr
题意是求一个字符串每个长度的子串出现次数最多的那个出现了多少次,也就是求每个到根的最长路的right集合最大值 。
先建后缀自动机,然后将每个前缀所在的集合的初值设为1,因为所有前缀的right集合肯定不相同,而且它们包含了所有位置。
接下来按到根的最长距离从大到小排序,将right集合累加到parent上。这么排序是因为到根的最长距离长的状态肯定不是到根的最长距离短的状态的parent。
最后直接求到根的不同的最长距离的最大的right集合就行。
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define maxn 250010
using namespace std;
int ans,len,p;
int read()
{
int f=,x=;char ch=getchar();
while(isdigit(ch)== && ch!='-')ch=getchar();
if(ch=='-')f=-,ch=getchar();
while(isdigit(ch))x=x*+ch-'',ch=getchar();
return x*f;
}
void write(int x)
{
int ff=;char ch[];
while(x)ch[++ff]=(x%)+'',x/=;
if(ff==)putchar('');
while(ff)putchar(ch[ff--]);
putchar('\n');
}
typedef struct node
{
int to[],dis,fa;
}spot;
//求每个dis的right集合最大值
//不是每个状态的right集合!!
//ass♂we♂can♂
struct SAM
{
spot x[maxn<<];
int ls,ls2,q,cnt,rt,lst,c[maxn<<],ord[maxn<<],ans[maxn<<],maxl[maxn<<];
int right[maxn<<],f[maxn<<];
char s[maxn];
inline void start()
{
lst=rt=++cnt;
scanf("%s",s+);
ls=strlen(s+);
for(int i=;i<=ls;i++)
extend(i);
}
inline void extend(int pos)
{
int val=s[pos]-'a',p=lst,np=++cnt;
lst=np,x[np].dis=pos;
for(;p&&x[p].to[val]==;p=x[p].fa)x[p].to[val]=np;
if(p==)x[np].fa=rt;
else
{
int q=x[p].to[val];
if(x[q].dis==x[p].dis+)x[np].fa=q;
else
{
int nq=++cnt;
x[nq].dis=x[p].dis+;
memcpy(x[nq].to,x[q].to,sizeof(x[q].to));
x[nq].fa=x[q].fa,x[np].fa=x[q].fa=nq;
for(;x[p].to[val]==q;p=x[p].fa)x[p].to[val]=nq;
}
}
}
inline void qsort()
{
for(int i=;i<=cnt;i++)
c[x[i].dis]++;
for(int i=;i<=ls;i++)
c[i]+=c[i-];
for(int i=;i<=cnt;i++)
ord[c[x[i].dis]--]=i;
}
inline void work()
{
for(int i=,p=rt;i<=ls;i++)
p=x[p].to[s[i]-'a'],right[p]=;
for(int i=cnt;i>=;i--){int u=ord[i];right[x[u].fa]+=right[u];}
for(int i=;i<=cnt;i++)f[x[i].dis]=max(f[x[i].dis],right[i]);
for(int i=ls;i>=;i--)f[i]=max(f[i],f[i+]);
for(int i=;i<=ls;i++)write(f[i]);
// cout<<"He doesn't have hands->"<<endl;
}
}t;
int main()
{
t.start();
t.qsort();
t.work();
return ;
}
并不对劲的SAM
听某位大佬说后缀自动机能解决所有不是字符串dp的字符串题。
并不对劲的spoj nsubstr的更多相关文章
- SPOJ - NSUBSTR 后缀自动机板子
SPOJ - NSUBSTR #include<bits/stdc++.h> #define LL long long #define fi first #define se second ...
- SPOJ NSUBSTR (后缀自动机)
SPOJ NSUBSTR Problem : 给一个长度为n的字符串,要求分别输出长度为1~n的子串的最多出现次数. Solution :首先对字符串建立后缀自动机,在根据fail指针建立出后缀树,对 ...
- 【spoj NSUBSTR】 Substrings
http://www.spoj.com/problems/NSUBSTR/ (题目链接) 题意 给出一个字符串S,令${F(x)}$表示S的所有长度为x的子串出现次数的最大值.求${F(1)..... ...
- SPOJ NSUBSTR Substrings 后缀自动机
人生第一道后缀自动机,总是值得纪念的嘛.. 后缀自动机学了很久很久,先是看CJL的论文,看懂了很多概念,关于right集,关于pre,关于自动机的术语,关于为什么它是线性的结点,线性的连边.许多铺垫的 ...
- SPOJ NSUBSTR
You are given a string S which consists of 250000 lowercase latin letters at most. We define F(x) as ...
- SPOJ NSUBSTR Substrings
题意 dt { font-weight: bold; margin-top: 20px; padding-left: 35px; } dd { box-shadow: 3px 3px 6px #888 ...
- SPOJ - NSUBSTR(长度为1-len的字串出现的最大次数
题意:给你一个字符串,要你输出1-len的字串出现的最大次数. /** @xigua */ #include <stdio.h> #include <cmath> #inclu ...
- 【SPOJ -NSUBSTR】Substrings 【后缀自动机+dp】
题意 给出一个字符串,要你找出所有长度的子串分别的最多出现次数. 分析 我们建出后缀自动机,然后预处理出每个状态的cnt,cnt[u]指的是u这个状态的right集合大小.我们设f[len]为长度为l ...
- SPOJ NSUBSTR Substrings ——后缀自动机
建后缀自动机 然后统计次数,只需要算出right集合的大小即可, 然后更新f[l[i]]和rit[i]取个max 然后根据rit集合短的一定包含长的的性质,从后往前更新一遍即可 #include &l ...
随机推荐
- IDEA基本使用及配置(2)
IDEA配置:File >> Setiings进入配置界面 1.主题配置:默认两种主题,黑色.白色,可以自己在网上下载,然后File >> Import Setiings导入, ...
- python字符串,常用编码
Python的字符串和编码 1.常用编码 与python有关的编码主要有:ASCII.Unicode.UTF-8 其中ASCII如今可以视作UTF-8的子集 内存中统一使用Unicode编码(如记事本 ...
- LeetCode(88)Merge Sorted Array
题目 Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note ...
- PLSQLDeveloper安装与配置(详细图文)
PLSQLDeveloper安装与配置(详细图文) 听语音 | 浏览:21912 | 更新:2016-10-24 17:12 1 2 3 4 5 6 7 分步阅读 在公司做项目时需要使用PLSQL D ...
- BNUOJ 5997 Fibonacci again and again
Fibonacci again and again Time Limit: 1000ms Memory Limit: 32768KB This problem will be judged on HD ...
- [luoguP1010] 幂次方 ^(* ̄(oo) ̄)^
传送门 递归.. 代码 #include <cstdio> int n; int bit[15]; inline void solve(int x) { int i, f = 0; if( ...
- Linux下汇编语言学习笔记17 ---
这是17年暑假学习Linux汇编语言的笔记记录,参考书目为清华大学出版社 Jeff Duntemann著 梁晓辉译<汇编语言基于Linux环境>的书,喜欢看原版书的同学可以看<Ass ...
- 静态区间第k大(分桶法和平方分割)
POJ 2104为例 思想: <挑战程序设计竞赛>中介绍的方法. 分桶法:把一排物品或者平面分成桶,每个桶分别维护自己内部的信息,已达到高效计算的目的. 设一共有n个数,每b个分到一个桶里 ...
- 逆袭指数-——杭电校赛(dfs)
逆袭指数 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- 在springBoot与quartz 整合中 @Transaction 失效
问题1::springBoot在与quartz 整合时,使用@Transaction 注解时事务失效 解决方案:创建一个类使用@component被spring管理 ,使用@Transaction标识 ...