1. 程式人生 > >SPOJ7258 SUBLEX - Lexicographical Substring Search

SPOJ7258 SUBLEX - Lexicographical Substring Search

傳送門[洛谷]

心態崩了我有妹子

靠 我寫的記憶化搜尋 莫名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\n",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("\n");
    }
    return 0;
}