HDU 4622 Reincarnation SAM

来源:互联网 发布:国泰君安 mac 编辑:程序博客网 时间:2024/05/24 01:16

-------------

Reincarnation

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)
Total Submission(s): 1439    Accepted Submission(s): 503


Problem Description
Now you are back,and have a task to do:
Given you a string s consist of lower-case English letters only,denote f(s) as the number of distinct sub-string of s.
And you have some query,each time you should calculate f(s[l...r]), s[l...r] means the sub-string of s start from l end at r.
 

Input
The first line contains integer T(1<=T<=5), denote the number of the test cases.
For each test cases,the first line contains a string s(1 <= length of s <= 2000).
Denote the length of s by n.
The second line contains an integer Q(1 <= Q <= 10000),denote the number of queries.
Then Q lines follows,each lines contains two integer l, r(1 <= l <= r <= n), denote a query.
 

Output
For each test cases,for each query,print the answer in one line.
 

Sample Input
2bbaba53 42 22 52 41 4baaba53 33 41 43 55 5
 

Sample Output
3175813851
Hint
I won't do anything against hash because I am nice.Of course this problem has a solution that don't rely on hash.
 

Source
2013 Multi-University Training Contest 3
 

Recommend
zhuyuanchen520
 

-------------

后缀自动机啊,真是不明觉厉

-------------

#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#include <climits>#include <numeric>#include <vector>#define sz(x) int(x.size())using namespace std;typedef vector<int> VI;const int maxn = 5000 + 10;class SuffixAutomaton{private:    struct Node{        Node *suf, *go[26];        int val;        Node(){            suf=NULL;            val=0;            memset(go,0,sizeof(go));        }        void clear(){            suf=NULL;            val=0;            memset(go,0,sizeof(go));        }        int calc(){            if (suf==0) return 0;            return val-suf->val;        }    };    Node *root,*last;    Node nodePool[maxn*2],*cur;    Node* newNode(){        Node* res=cur++;        res->clear();        return res;    }    int tot;    void extend(int w){        Node *p=last;        Node *np=newNode();        np->val=p->val+1;        while (p&&!p->go[w]){            p->go[w]=np;            p=p->suf;        }        if (!p){            np->suf=root;            tot+=np->calc();        }        else{            Node *q=p->go[w];            if (p->val+1==q->val){                np->suf=q;                tot+=np->calc();            }            else{                Node *nq=newNode();                memcpy(nq->go,q->go,sizeof(q->go));                tot-=p->calc()+q->calc();                nq->val=p->val+1;                nq->suf=q->suf;                q->suf=nq;                np->suf=nq;                tot+=p->calc()+q->calc()+np->calc()+nq->calc();                while (p&&p->go[w]==q){                    p->go[w]=nq;                    p=p->suf;                }            }        }        last = np;    }public:    void init(){        cur=nodePool;        root=newNode();        last=root;    }    VI getSubString(char s[]){        VI v;        tot=0;        int len=strlen(s);        for (int i=0;i<len;i++){            extend(s[i]-'a');            v.push_back(tot);        }        return v;    }}atm;int ans[maxn][maxn];char s[maxn];int main() {int T;scanf("%d",&T);while (T--){    scanf("%s",s);    int len=strlen(s);    for (int i=0;i<len;i++){            atm.init();            VI v=atm.getSubString(s+i);            for (int j=0;j<sz(v);j++) ans[i][i+j]=v[j];    }    int nQ;        scanf("%d",&nQ);        while (nQ--){            int l,r;            scanf("%d%d",&l,&r);            printf("%d\n",ans[l-1][r-1]);        }}return 0;}


-------------

-------------

-------------

-------------

-------------


原创粉丝点击