zoukankan      html  css  js  c++  java
  • POJ 3415 Common Substrings

    Common Substrings

    Time Limit: 5000ms
    Memory Limit: 65536KB
    This problem will be judged on PKU. Original ID: 3415
    64-bit integer IO format: %lld      Java class name: Main

    A substring of a string T is defined as:

    [T(i, k)=T_iT_{i+1}dots T_{i+k-1}, 1leq ileq i+k-1leq |T|.]

    Given two strings AB and one integer K, we define S, a set of triples (ijk):

    [S = {(i, j, k) | kgeq K, A(i, k)=B(j, k)}.]

    You are to give the value of |S| for specific AB and K.

     

    Input

    The input file contains several blocks of data. For each block, the first line contains one integer K, followed by two lines containing strings A and B, respectively. The input file is ended by K=0.

    $1 leq |A|, |B| leq 10^5,1 leq  Kleq  min{|A|, |B|}$ Characters of A and B are all Latin letters.

     

    Output

    For each case, output an integer |S|.

     

    Sample Input

    2
    aababaa
    abaabaa
    1
    xx
    xx
    0
    

    Sample Output

    22
    5
    

    Source

     
    解题:后缀自动机
      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstring>
      4 using namespace std;
      5 const int maxn = 100010;
      6 typedef long long LL;
      7 int ha(char ch){
      8     if(ch >= 'a' && ch <= 'z') return ch - 'a';
      9     return ch - 'A' + 26;
     10 }
     11 struct SAM{
     12     struct node{
     13         int son[52],f,len;
     14         void init(int _len){
     15             f = -1;
     16             len = _len;
     17             memset(son,-1,sizeof son);
     18         }
     19     }e[maxn<<1];
     20     int cnt[maxn<<1],lazy[maxn<<1],tot,last;
     21     int c[maxn<<1],sa[maxn<<1];
     22     int newnode(int len = 0){
     23         e[tot].init(len);
     24         return tot++;
     25     }
     26     void init(){
     27         tot = last = 0;
     28         memset(cnt,0,sizeof cnt);
     29         memset(lazy,0,sizeof lazy);
     30         memset(c,0,sizeof c);
     31         newnode();
     32     }
     33     void extend(int c){
     34         int p = last,np = newnode(e[p].len + 1);
     35         while(p != -1 && e[p].son[c] == -1){
     36             e[p].son[c] = np;
     37             p = e[p].f;
     38         }
     39         if(p == -1) e[np].f = 0;
     40         else{
     41             int q = e[p].son[c];
     42             if(e[p].len + 1 == e[q].len) e[np].f = q;
     43             else{
     44                 int nq = newnode();
     45                 e[nq] = e[q];
     46                 e[nq].len = e[p].len + 1;
     47                 e[np].f = e[q].f = nq;
     48                 while(p != -1 && e[p].son[c] == q){
     49                     e[p].son[c] = nq;
     50                     p = e[p].f;
     51                 }
     52             }
     53         }
     54         cnt[last = np] = 1;
     55     }
     56     void update(){
     57         for(int i = tot-1; i > 0; --i)
     58             cnt[e[sa[i]].f] += cnt[sa[i]];
     59     }
     60     void sort(int len){
     61         for(int i = 0; i < tot; ++i) c[e[i].len]++;
     62         for(int i = 1; i <= len; ++i) c[i] += c[i-1];
     63         for(int i = tot-1; i >= 0; --i) sa[--c[e[i].len]] = i;
     64     }
     65     LL solve(char str[],int k,LL ret = 0){
     66         int p = 0,tmp = 0;
     67         for(int i = 0; str[i]; ++i){
     68             int c = ha(str[i]);
     69             if(~e[p].son[c]){
     70                 p = e[p].son[c];
     71                 ++tmp;
     72             }else{
     73                 while(p != -1 && e[p].son[c] == -1) p = e[p].f;
     74                 if(p == -1) {
     75                     p = 0;
     76                     tmp = 0;
     77                 }else{
     78                     tmp = e[p].len + 1;
     79                     p = e[p].son[c];
     80                 }
     81             }
     82             if(tmp >= k){
     83                 ret += (tmp - max(k,e[e[p].f].len + 1) + 1)*cnt[p];
     84                 if(k <= e[e[p].f].len) ++lazy[e[p].f];
     85             }
     86         }
     87         for(int i = tot-1; i > 0; --i){
     88             int u = sa[i];
     89             ret += (LL)lazy[u]*(e[u].len - max(k,e[e[u].f].len + 1) + 1)*cnt[u];
     90             if(k <= e[e[u].f].len) lazy[e[u].f] += lazy[u];
     91         }
     92         return ret;
     93     }
     94 }sam;
     95 char str[maxn];
     96 int main(){
     97     int k;
     98     while(scanf("%d",&k),k){
     99         scanf("%s",str);
    100         sam.init();
    101         for(int i = 0; str[i]; ++i)
    102             sam.extend(ha(str[i]));
    103         sam.sort(strlen(str));
    104         sam.update();
    105         scanf("%s",str);
    106         printf("%lld
    ",sam.solve(str,k));
    107     }
    108     return 0;
    109 }
    View Code
  • 相关阅读:
    成功更容易光顾磨难和艰辛,正如只有经过泥泞的道路才会留下脚印
    只要信心在,勇气就在,努力在,成功就在!
    不积跬步无以至千里,不积小流无以成江海
    你给自己留的退路越多,你失败的可能性就越大
    不要质疑你的付出,这些都会是一种累积一种沉淀,它们会默默铺路,只为让你成为更优秀的人
    生活的一大乐趣便是完成别人认为你不能做到的事情
    优于别人,并不高贵,真正的高贵,是优于过去的自己
    再长的路 ,一步步也能走完,再短的路,不迈开双脚也不无法到达!
    09SpringAopAdvice
    java中接口(interface)和虚基类(abstract class)的区别
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4912348.html
Copyright © 2011-2022 走看看