spoj NSUBSTR - Substrings【SAM】
先求个SAM,然后再每个后缀的对应点上标记si[nw]=1,造好SAM之后用吧parent树建出来把si传上去,然后用si[u]更新f[max(u)],最后用j>i的[j]更新f[i]
因为每个点u对应长为min(u)~max(u)的串,我们就把它记在max(u)上,最后再统一向前更新,然后更新后的si就表示right大小,也就是这个串对应的后缀个数
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=1000005;
int n,fa[N],ch[N][27],dis[N],si[N],cur=1,con=1,la,h[N],cnt,f[N];
char s[N];
struct qwe
{
	int ne,to;
}e[N<<2];
void add(int u,int v)
{
	cnt++;
	e[cnt].ne=h[u];
	e[cnt].to=v;
	h[u]=cnt;
}
void ins(int c,int id)
{
	la=cur,dis[cur=++con]=id,si[cur]=1;
	int p=la;
	for(;p&&!ch[p][c];p=fa[p])
		ch[p][c]=cur;
	if(!p)
		fa[cur]=1;
	else
	{
		int q=ch[p][c];
		if(dis[q]==dis[p]+1)
			fa[cur]=q;
		else
		{
			int nq=++con;
			dis[nq]=dis[p]+1;
			memcpy(ch[nq],ch[q],sizeof(ch[q]));
			fa[nq]=fa[q];
			fa[q]=fa[cur]=nq;
			for(;ch[p][c]==q;p=fa[p])
				ch[p][c]=nq;
		}
	}
}
void dfs(int u)
{
	for(int i=h[u];i;i=e[i].ne)
	{
		dfs(e[i].to);
		si[u]+=si[e[i].to];
	}
	f[dis[u]]=max(f[dis[u]],si[u]);
}
int main()
{
	scanf("%s",s+1);
	n=strlen(s+1);
	for(int i=1;i<=n;i++)
		ins(s[i]-'a',i);
	for(int i=2;i<=con;i++)
		add(fa[i],i);
	dfs(1);
	for(int i=n-1;i>=1;i--)
		f[i]=max(f[i],f[i+1]);
	for(int i=1;i<=n;i++)
		printf("%d\n",f[i]);
	return 0;
}
spoj NSUBSTR - Substrings【SAM】的更多相关文章
- 【SAM】codevs3160-最长公共子串
		[题目大意] 求两个字符串的最长公共子串. [思路] 对第一个字符串建立后缀自动机,第二个字符串去匹配.cnt记录当前最长公共子串的长度,而ret记录答案. p代表位置指针,初始在rt位置. 对于第二 ... 
- 【SAM】BZOJ2882-工艺
		[题目大意] 求一个循环数列的最小表示法. [思路] 最小表示法的正解:★ SAM乱搞,和前面的POJ那道一样.然而MLE了,当作学习一下map的用法^ ^ map的使用方法(来源:☆) 一.map的 ... 
- 【SAM】BZOJ3998-弦论
		[题目大意] 给出一个字符串,求第k大的子串.(输入1表示子串可重复,0表示不可重复) [思路] 显然,k大子串是后缀自动机的经典题型,可以利用后缀自动机的性质来解决.对于字符串 [前铺1]" ... 
- 【SAM】POJ1509-Glass Beads
		[题目大意] 求一个循环数列的最小表示法. [思路] 把原创复制一遍放在后面,建立SAM,从s按字典序开始跑长度L即可. 板子来源(作者见连接内): 
- spoj SUBST1 - New Distinct Substrings【SAM||SA】
		SAM里的转台不会有重复串,所以答案就是每个right集合所代表的串个数的和 #include<iostream> #include<cstdio> #include<c ... 
- SPOJ Distinct Substrings【后缀数组】
		Given a string, we need to find the total number of its distinct substrings. Input T- number of test ... 
- 【SPOJ - LCS2】Longest Common Substring II【SAM】
		题意 求出多个串的最长公共子串. 分析 刚学SAM想做这个题的话最好先去做一下那道codevs3160.求两个串的LCS应该怎么求?把一个串s1建自动机,然后跑另一个串s2,然后找出s2每个前缀的最长 ... 
- spoj LCS2 - Longest Common Substring II && LCS - Longest Common Substring【SAM】
		多串LCS很适合SA但是我要学SAM 对第一个串求SAM,然后把剩下的串在SAM上跑,也就是维护p和len,到一个点,如果有ch[p][c],就p=ch[p][c],len++,否则向fa找最下的有c ... 
- spoj SUBLEX - Lexicographical Substring Search【SAM】
		先求出SAM,然后考虑定义,点u是一个right集合,代表了长为dis[son]+1~dis[u]的串,然后根据有向边转移是添加一个字符,所以可以根据这个预处理出si[u],表示串u后加字符能有几个本 ... 
随机推荐
- linux的主分区与逻辑分区的关系
			 主分区和扩展分区的差别在于主分区位于硬盘的最開始.MBR 扇区的位置.这个位置的数据在计算机启动时.会自己主动被 BIOS 读取而且运行,也就是说这个位置的分区表会自己主动被 BIOS 读取到内 ... 
- 多线程网页爬虫 python 实现
			采用了多线程和锁机制,实现了广度优先算法的网页爬虫. 对于一个网络爬虫,如果要按广度遍历的方式下载,它就是这样干活的: 1.从给定的入口网址把第一个网页下载下来 2.从 ... 
- 一套扁平化界面风格的flex 皮肤
			意外在git上发现这个项目.似乎刚開始不久.部分控件的新皮肤似乎还没完毕.只是个人感觉挺不错的.大家认为呢? =>git地址:https://github.com/akamud/FlatSpar ... 
- putty software caused connection abort
			错误现象:在非常短的时间内就失去连接.并报"Software caused connection abort" 解决的方法:首先得排除是网络不是不通畅.假设在局域网中要确定IP没有 ... 
- IMP-00009  And  IMP-00028
			导出文件异常结束” 错误,google一下,发现可能有如下原因导致 1.imp的数据太大,没有写buffer和commit 2.两个数据库字符集不同 3.从低版本exp的dmp文件,向高版本imp 4 ... 
- C# 给窗体添加事件
			1.https://zhidao.baidu.com/question/588485101.html 
- HDU 1081:To The Max
			To The Max Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total ... 
- 正则表达式、Calendar类、SimpleDateFormat类、Date类、BigDecimal类、BigInteger类、System类、Random类、Math类(Java基础知识十四)
			1.正则表达式的概述和简单使用 * A:正则表达式(一个字符串,是规则) * 是指一个用来描述或者匹配一系列符合某个语法规则的字符串的单个字符串.其实就是一种规则.有自己特殊的应用. * B: ... 
- Silverlight中使用MVVM(4)
			Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ... 
- Android API中的对话框
			Android API中提供了四个Dialog的自定义子类: AlertDialog ProgressDialog DatePackerDialog TimePickerDialog 也可以派生出自己 ... 
