• POJ3729 Facer’s string 后缀数组


                                                                                                      Facer’s string
    Time Limit: 3000MS   Memory Limit: 65536K
    Total Submissions: 1783   Accepted: 537

    Description

    Minifacer was very happy these days because he has learned the algorithm of KMP recently. Yet his elder brother, Hugefacer, thought that Minifacer needs a deeper understanding of this algorithm. Thus Hugefacer decided to play a game with his little brother to enhance his skills.

    First, Hugefacer wrote down two strings S1 and S2. Then Minifacer tried to find a substring S3 of S1 which meets the following requirements: 1) S3 should have a length of k (which is a constant value); 2)S3 should also be the substring of S2. After several rounds, Hugefacer found that this game was too easy for his clever little brother, so he added another requirement: 3) the extended string of S3 should NOT be the substring of S2. Here the extended string of S3 is defined as S3 plus its succeed character in S1 (if S3 does not have a succeed character in S1, the extended string of S3 is S3 + ' ' which will never appear in S2). For example, let S1 be "ababc", if we select the substring from the first character to the second character as S3 (so S3 equals "ab"), its extended string should be "aba"; if we select the substring from the third character to the fourth character as S3, its extended string should be "abc"; if we select the substring from the fourth character to the fifth character as S3, its extended string should be "bc".

    Since the difficult level of the game has been greatly increased after the third requirement was added, Minifacer was not able to win the game and he thought that maybe none of the substring would meet all the requirements. In order to prove that Minifacer was wrong, Hugefacer would like to write a program to compute number of substrings that meet the three demands (Note that two strings with same appearance but different positions in original string S1 should be count twice). Since Hugefacer do not like characters, he will use non-negative integers (range from 0 to 10000) instead.

    Input

    There are multiple test cases. Each case contains three lines: the first line contains three integers nm and k where n represents the length of S1m represents the length of S2 and k represents the length of substring; the second line contains string S1 and the third line contains string S2. Here 0 ≤ nm ≤ 50000. Input ends with EOF.

    Output

    For each test case, output a number in a line stand for the total number of substrings that meet the three requirements.

    Sample Input

    5 5 2
    1 2 1 2 3
    1 2 3 4 5
    5 5 3
    1 2 1 2 3
    1 2 3 4 5
    

    Sample Output

    2
    1

    大致意思: a串所有后缀中,有多少个后缀与b串的所有后缀的lcp的最大值==k。。

    a b串先连接一下,,中间加一个不会出现的数值,,我选了inf。。

    然后求sa,lcp数组。。

    可以先求大于等于k的后缀个数 ,再减去大于等于k+1的个数就是答案了。。

      1 #include <set>
      2 #include <map>
      3 #include <cmath>
      4 #include <ctime>
      5 #include <queue>
      6 #include <stack>
      7 #include <cstdio>
      8 #include <string>
      9 #include <vector>
     10 #include <cstdlib>
     11 #include <cstring>
     12 #include <iostream>
     13 #include <algorithm>
     14 using namespace std;
     15 typedef unsigned long long ull;
     16 typedef long long ll;
     17 const int inf = 0x3f3f3f3f;
     18 const double eps = 1e-8;
     19 const int maxn = 5e4+10;
     20 int s[maxn<<1];
     21 int len, k, sa[maxn << 1], tmp[maxn << 1], rank[maxn << 1];
     22 bool cmp(int i, int j)
     23 {
     24     if (rank[i] != rank[j])
     25         return rank[i] < rank[j];
     26     else
     27     {
     28         int x = (i + k <= len ? rank[i+k] : -1);
     29         int y = (j + k <= len ? rank[j+k] : -1);
     30         return x < y;
     31     }
     32 }
     33 void build_sa()
     34 {
     35     for (int i = 0; i <= len; i++)
     36     {
     37         sa[i] = i;
     38         rank[i] = (i < len ? s[i] : -1);
     39     }
     40     for (k = 1; k <= len; k *= 2)
     41     {
     42         sort(sa, sa+len+1,cmp);
     43         tmp[sa[0]] = 0;
     44         for (int i = 1; i <= len; i++)
     45         {
     46             tmp[sa[i]] = tmp[sa[i-1]] + (cmp(sa[i-1], sa[i]) ? 1 : 0);
     47         }
     48         for (int i = 0; i <= len; i++)
     49             rank[i] = tmp[i];
     50     }
     51 }
     52 int lcp[maxn << 1];
     53 void get_lcp()
     54 {
     55     for (int i = 0; i <= len; i++)
     56     {
     57         rank[sa[i]] = i;
     58     }
     59     int h = 0;
     60     lcp[0] = 0;
     61     for (int i = 0; i < len; i++)
     62     {
     63         int j = sa[rank[i]-1];
     64         if (h > 0)
     65             h--;
     66         for (; j+h < len && i+h < len; h++)
     67             if (s[j+h] != s[i+h])
     68                 break;
     69         lcp[rank[i]] = h;
     70     }
     71 }
     72 int solve(int kk, int n)
     73 {
     74     int res = 0;
     75     for (int i = 0; i <= len; i++)
     76     {
     77         if (lcp[i] >= kk)
     78         {
     79             int one = 0, two = 0;
     80             if (sa[i-1] < n)
     81                 one++;
     82             if (sa[i-1] > n)
     83                 two++;
     84             for (; i < len && lcp[i] >= kk; i++)
     85             {
     86                 if (sa[i] < n)
     87                     one++;
     88                 if (sa[i] > n)
     89                     two++;
     90             }
     91             if (two)
     92                 res += one;
     93         }
     94     }
     95     return res;
     96 }
     97 int main()
     98 {
     99     #ifndef ONLINE_JUDGE
    100         freopen("in.txt","r",stdin);
    101     #endif
    102     int n,m,kk;
    103     while (~ scanf ("%d%d%d",&n,&m,&kk))
    104     {
    105         for (int i = 0; i < n; i++)
    106         {
    107             scanf ("%d", s+i);
    108             s[i]++;
    109         }
    110         s[n] = inf;
    111         for (int i = n+1; i < n+1+m; i++)
    112         {
    113             scanf ("%d", s+i);
    114             s[i]++;
    115         }
    116         len  = n + m + 1;
    117         build_sa();
    118         get_lcp();
    119         printf("%d
    ",solve(kk,n) - solve(kk+1,n));
    120     }
    121     return 0;
    122 }
  • 相关阅读:
    开源cms系统We7插件开发准备工作全面就绪 开源CMS
    We7促销力度惊人:又开源又送iphone! 开源CMS
    开源cms系统:We7 CMS 2.5版内测版发布啦! 开源CMS
    开源cms系统的发展趋势 开源CMS
    We7 CMS支撑全新宁夏检察院门户网站 开源CMS
    We7开放式维基文档中心正式开通 开源CMS
    我公司签约成都申达科技打造校园行业网站群建设新的应用平台 开源CMS
    西部动力中标北京京能热电股份有限公司班组管理系统网站群项目 开源CMS
    SQL查数据库表,字段
    DataTable Excel
  • 原文地址:https://www.cnblogs.com/oneshot/p/4337686.html
Copyright © 2020-2023  润新知