zoukankan      html  css  js  c++  java
  • POJ3415 Common Substrings

    后缀数组 求长度不小于k的公共子串的个数

    代码:

      1 #include <stdio.h>
      2 #include <string.h>
      3 
      4 const int maxn = 200011;
      5 int len, len1;
      6 int wa[maxn], wb[maxn], wv[maxn], wd[maxn], sa[maxn];
      7 int lcp[maxn], r[maxn], rank[maxn], height[maxn];
      8 
      9 int cmp(int *r, int a, int b, int l){
     10     return r[a] == r[b] && r[a+l] == r[b+l];
     11 }
     12 
     13 void da(int *r, int n, int m){
     14     int i, j, p, *x=wa, *y=wb, *t;
     15     for(i = 0; i < m; i++) wd[i] = 0;
     16     for(i = 0; i < n; i++) wd[x[i] = r[i]]++;
     17     for(i = 1; i < m; i++) wd[i] += wd[i-1];
     18     for(i = n-1; i >= 0; i--) sa[--wd[x[i]]] = i;
     19     for(j = 1, p = 1; p < n; j *= 2, m = p){
     20         for(p = 0, i = n-j; i < n; i++) y[p++] = i;
     21         for(i = 0; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;
     22         for(i = 0; i < n; i++) wv[i] = x[y[i]];
     23         for(i = 0; i < m; i++) wd[i] = 0;
     24         for(i = 0; i < n; i++) wd[wv[i]]++;
     25         for(i = 1; i < m; i++) wd[i] += wd[i-1];
     26         for(i = n-1; i >= 0; i --) sa[--wd[wv[i]]] = y[i];
     27         for(t = x, x = y, y = t, p = 1, x[sa[0]] = 0, i = 1; i < n; i++){
     28             x[sa[i]] = cmp(y, sa[i-1], sa[i], j) ? p-1: p++;
     29         }
     30     }
     31 }
     32 
     33 void calHeight(int *r, int n){
     34     int i, j, k = 0;
     35     for(i = 1; i <= n; i++) rank[sa[i]] = i;
     36     for(i = 0; i < n; height[rank[i++]] = k){
     37         for(k ? k-- : 0, j = sa[rank[i]-1]; r[i+k] == r[j+k]; k++);
     38     }
     39 }
     40 
     41 int main(){
     42     int k;
     43     char str1[maxn], str2[maxn];
     44     while(~scanf("%d", &k)){
     45         if(k==0) break;
     46         scanf("%s%s",str1, str2);
     47         len1 = strlen(str1);
     48         len = strlen(str2);
     49         for(int i = 0; i < len1; i++){
     50             r[i] = str1[i];
     51         }
     52         r[len1] = '$';
     53         for(int i = 0; i < len; i++){
     54             r[i+len1+1] = str2[i];
     55         }
     56         len += len1+1;
     57         r[len] = 0;
     58         da(r, len+1, 150);
     59         calHeight(r, len);
     60         long long res = 0, sum;
     61         int head, tail;
     62         for(int i = 1; i <= len; i++){
     63             if(height[i] < k){
     64                 sum = 0;
     65                 head = tail = maxn;
     66             }
     67             else{
     68                 for(int j = head; j < tail; j++){
     69                     if(lcp[j] > height[i]){
     70                         sum -= lcp[j]-height[i];
     71                         lcp[j] = height[i];
     72                     }
     73                     else break;
     74                 }
     75                 if(sa[i-1] > len1){
     76                     lcp[--head] = height[i];
     77                     sum += lcp[head]-k+1;
     78                 }
     79                 if(sa[i] < len1) res += sum;
     80             }
     81         }
     82         for(int i = 1; i <= len; i++){
     83             if(height[i] < k){
     84                 sum = 0;
     85                 head = tail = maxn;
     86             }
     87             else{
     88                 for(int j = head; j < tail; j++){
     89                     if(lcp[j] > height[i]){
     90                         sum -= lcp[j]-height[i];
     91                         lcp[j] = height[i];
     92                     }
     93                     else break;
     94                 }
     95                 if(sa[i-1] < len1){
     96                     lcp[--head] = height[i];
     97                     sum += lcp[head]-k+1;
     98                 }
     99                 if(sa[i] > len1) res += sum;
    100             }
    101         }
    102         printf("%I64d
    ", res);
    103     }
    104 }
  • 相关阅读:
    BZOJ1527 : [POI2005]Pun-point
    2016-2017 ACM-ICPC Southwestern European Regional Programming Contest (SWERC 2016)
    2016-2017 ACM-ICPC Northwestern European Regional Programming Contest (NWERC 2016)
    NAIPC-2016
    BZOJ2498 : Xavier is Learning to Count
    ACM ICPC Vietnam National Second Round
    XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
    XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
    HDU5509 : Pattern String
    BZOJ4583 : 购物
  • 原文地址:https://www.cnblogs.com/pony1993/p/3427497.html
Copyright © 2011-2022 走看看