zoukankan      html  css  js  c++  java
  • spoj NSUBSTR

    先求个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
    ",f[i]);
    	return 0;
    }
    
  • 相关阅读:
    西安.NET俱乐部群 推广代码
    跟我学Makefile(六)
    跟我学Makefile(五)
    跟我学Makefile(四)
    跟我学Makefile(三)
    跟我学Makefile(二)
    Kconfig文件说明2
    Kconfig文件说明
    kernel内核配置说明
    makefile中ifeq与ifneq dev/null和dev/zero简介 dd命令
  • 原文地址:https://www.cnblogs.com/lokiii/p/10001924.html
Copyright © 2011-2022 走看看