SPOJ7258 SUBLEX

传送门[洛谷]

心态崩了我有妹子

靠 我写的记忆化搜索 莫名WA了 然后心态崩了

当我正要改成bfs排序的时候 我灵光一动 md我写的i=0;i<25;i++???

然后 改过来就A掉了T^T

大体做法就是 一个点出发的本质不同子串数量应该是(sum _{i=0}^{w} f[x][ch[x][i]])+1就是所有添加字符的转移和其余选一个空串的转移

所以直接建出自动机然后 我的做法是直接记忆化搜索就可以省去建树/排序 因为所有子串必定由转移构成 所以可以直接记忆化

附代码。(我觉得这个做法巨强无比)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define inf 20021225
#define ll long long
#define mxn 90010
using namespace std;

struct node{int ch[26],fa,len,f;}t[mxn*4];
int poi,cnt,lt,rt;char ch[mxn];
int id(char c){return c-'a';}
void insert(int c)
{
    int p=lt,np=lt=++poi; t[np].len=t[p].len+1;
    for(;p&&!t[p].ch[c];p=t[p].fa)	t[p].ch[c]=np;
    if(!p){t[np].fa=rt;return;}
    int q=t[p].ch[c];
    if(t[q].len==t[p].len+1){t[np].fa=q;return;}
    int nq=++poi; t[nq].len=t[p].len+1;
    memcpy(t[nq].ch,t[q].ch,sizeof(t[q].ch));
    t[nq].fa=t[q].fa; t[q].fa=t[np].fa=nq;
    for(;p&&t[p].ch[c]==q;p=t[p].fa) t[p].ch[c]=nq;
}
int query(int x)
{
    if(~t[x].f)	return t[x].f;
    t[x].f=1;
    for(int i=0;i<26;i++)
        if(t[x].ch[i])
            t[x].f+=query(t[x].ch[i]);
    return t[x].f;
}
int n;
void getans(int pos,int k)
{
    if(!k)	return;
    for(int i=0;i<26;i++)
        if(t[pos].ch[i])
        {
            if(t[t[pos].ch[i]].f<k)	k-=t[t[pos].ch[i]].f;
            else{ch[++n]=i+'a';getans(t[pos].ch[i],k-1);break;}
        }
}
int main()
{
    scanf("%s",ch+1);n=strlen(ch+1);
    rt=lt=++poi;for(int i=1;i<=n;i++)	insert(id(ch[i]));
    for(int i=1;i<=poi;i++)	t[i].f=-1;query(rt);
    //for(int i=1;i<=poi;i++)	printf("%d
",t[i].f);
    int T;scanf("%d",&T);
    while(T--)
    {
        for(int i=1;i<=n;i++)	ch[i]=0;
        int k;scanf("%d",&k);
        n=0;getans(rt,k);
        for(int i=1;i<=n;i++)	printf("%c",ch[i]);
        printf("
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/hanyuweining/p/10321916.html