zoukankan      html  css  js  c++  java
  • 字符串(后缀自动机):HDU 4622 Reincarnation

    Reincarnation

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


    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.
     
      程立杰出的题目?
      sam有个性质就是对于新加一个字符,产生的新子串个数为len[lst]-len[fa[lst]]。
     1 #include <iostream>
     2 #include <cstring>
     3 #include <cstdio>
     4 using namespace std;
     5 const int maxn=4010;
     6 int fa[maxn],ch[maxn][26];
     7 int len[maxn],lst,cnt;
     8 int dp[maxn][maxn];
     9 char s[maxn];
    10 struct Opt{
    11     void Init(){
    12         memset(ch,0,sizeof(ch));
    13         lst=cnt=1;
    14     }
    15     
    16     int Insert(int c){
    17         int p=lst,np=lst=++cnt;len[np]=len[p]+1;
    18         while(p&&ch[p][c]==0)ch[p][c]=np,p=fa[p];
    19         if(!p)fa[np]=1;
    20         else{
    21             int q=ch[p][c];
    22             if(len[q]==len[p]+1)fa[np]=q;
    23             else{
    24                 int nq=++cnt;len[nq]=len[p]+1;
    25                 memcpy(ch[nq],ch[q],sizeof(ch[q]));
    26                 fa[nq]=fa[q];fa[q]=fa[np]=nq;
    27                 while(ch[p][c]==q)ch[p][c]=nq,p=fa[p];
    28             }
    29         }
    30         return len[lst]-len[fa[lst]]; 
    31     }
    32 }SAM;
    33 int main(){
    34     int T,Q;
    35     scanf("%d",&T);
    36     while(T--){
    37         scanf("%s",s+1);
    38         int len=strlen(s+1);
    39         for(int i=1;i<=len;i++){
    40             SAM.Init();
    41             for(int j=i;j<=len;j++)
    42                 dp[i][j]=dp[i][j-1]+SAM.Insert(s[j]-'a');
    43         }
    44         scanf("%d",&Q);
    45         while(Q--){
    46             int l,r;
    47             scanf("%d%d",&l,&r);
    48             printf("%d
    ",dp[l][r]);
    49         }
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    带有参数的存储过程
    不实用数据库实现保存和查询功能
    http错误代码(快速了解错误所在)
    ListBox的应用(左边中的信息移至右边)
    省市县三级连动(数据在一个表中)
    简单的实现用户注册时,向其油箱发送激活码邮件,并进行状态处理。 .
    省级三连动(二)
    省市选择期三级联动
    百钱百鸡
    MySQL命令简单应用
  • 原文地址:https://www.cnblogs.com/TenderRun/p/5700259.html
Copyright © 2011-2022 走看看