zoukankan      html  css  js  c++  java
  • HDU 4622 Reincarnation SAM

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

    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
    2 bbaba 5 3 4 2 2 2 5 2 4 1 4 baaba 5 3 3 3 4 1 4 3 5 5 5
     

    Sample Output
    3 1 7 5 8 1 3 8 5 1
    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
     

    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
    ",ans[l-1][r-1]);
            }
    	}
    	return 0;
    }
    


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

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

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

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

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


  • 相关阅读:
    idea 本地tomcat启动控制台乱码问题
    继续mysql8navicat12连接登录的异常
    mysql8.0修改密码无效的问题
    markdown开源博客Gitblogv2.1版本发布更新
    Gitblog-v2.1.3版本发布更新
    Markdown博客系统Gitblog-V2.1版本代码更新
    使用Gitblog和Markdown搭建自己的博客网站
    MongoDB3.0集群配置文件自动生成器
    用redis实现社交产品中计数器
    InnoDB的doublewrite机制
  • 原文地址:https://www.cnblogs.com/cyendra/p/3681554.html
Copyright © 2011-2022 走看看