HDU5558后缀自动机模板题

来源:互联网 发布:茂名行知中学以前是 编辑:程序博客网 时间:2024/05/16 01:31
我只能说后缀自动机时间复杂度简直666     感叹clj神
#include <bits/stdc++.h>using namespace std;const int maxn=100005;const int SIGMA_SIZE=26;struct SAM_Node{    SAM_Node *par,*next[SIGMA_SIZE];    int len,id,pos;    SAM_Node(){}    SAM_Node(int _len)    {        par=0;        len=_len;        memset(next,0,sizeof(next));    }};SAM_Node node[maxn*2],*root,*last;int SAM_size;SAM_Node *newSAM_Node(int len){    node[SAM_size]=SAM_Node(len);    node[SAM_size].id=SAM_size;    return &node[SAM_size++];}SAM_Node *newSAM_Node(SAM_Node *p){    node[SAM_size]=*p;    node[SAM_size].id=SAM_size;    return &node[SAM_size++];}void SAM_init(){    SAM_size=0;    root=last=newSAM_Node(0);    node[0].pos=0;}void SAM_add(int x,int len){    SAM_Node *p=last,*np=newSAM_Node(p->len+1);    np->pos=len;    last=np;    while(p&&!p->next[x])    {        p->next[x]=np;        p=p->par;    }    if(!p)    {        np->par=root;        return ;    }    SAM_Node *q=p->next[x];    if(q->len==p->len+1)    {        np->par=q;        return ;    }    SAM_Node *nq=newSAM_Node(q);    nq->len=p->len+1;    q->par=nq;    np->par=nq;    while(p&&p->next[x]==q)    {        p->next[x]=nq;        p=p->par;    }}void slove(char *s){    SAM_init();    int len=strlen(s);    int now = 0;    while(now!=len){        SAM_Node *p = root;        int tot = 0;        while(now < len && p->next[ s[now]-'a' ]){            p = p->next[ s[now]-'a' ];            ++tot;            SAM_add(s[now]-'a',now+1);            ++now;        }        if(!tot){            SAM_add(s[now]-'a',now+1);            cout<<"-1 "<< (int)s[now++] <<endl;        }        else{            cout<<tot<<" "<< p->pos-tot <<endl;        }    }}char str[maxn];int main(){    ios::sync_with_stdio(false);    int T,cnt=0;    cin>>T;    while(T--){        cin>>str;        cout<<"Case #"<<++cnt<<":"<<endl;        slove(str);    }    return 0;}

0 0
原创粉丝点击