zoukankan      html  css  js  c++  java
  • SPOJ 705 New Distinct Substrings

    New Distinct Substrings

    Time Limit: 2000ms
    Memory Limit: 262144KB
    This problem will be judged on SPOJ. Original ID: SUBST1
    64-bit integer IO format: %lld      Java class name: Main
     

    Given a string, we need to find the total number of its distinct substrings.

    Input

    T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000

    Output

    For each test case output one number saying the number of distinct substrings.

    Example

    Input:
    2
    CCCCC
    ABABA
    
    Output:
    5
    9

    Source

     
    解题:求不同子串的个数。后缀数组lcp的应用。
     
     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cmath>
     5 #include <algorithm>
     6 #include <climits>
     7 #include <vector>
     8 #include <queue>
     9 #include <cstdlib>
    10 #include <string>
    11 #include <set>
    12 #include <stack>
    13 #define LL long long
    14 #define pii pair<int,int>
    15 #define INF 0x3f3f3f3f
    16 using namespace std;
    17 const int maxn = 50010;
    18 int rk[maxn],wb[maxn],wv[maxn],wd[maxn],lcp[maxn];
    19 bool cmp(int *r,int i,int j,int k){
    20     return r[i] == r[j] && r[i+k] == r[j+k];
    21 }
    22 void da(int *r,int *sa,int n,int m){
    23     int i,k,p,*x = rk,*y = wb;
    24     for(i = 0; i < m; ++i) wd[i] = 0;
    25     for(i = 0; i < n; ++i) wd[x[i] = r[i]]++;
    26     for(i = 1; i < m; ++i) wd[i] += wd[i-1];
    27     for(i = n-1; i >= 0; --i) sa[--wd[x[i]]] = i;
    28 
    29     for(p = k = 1; p < n; k <<= 1,m = p){
    30         for(p = 0,i = n-k; i < n; ++i) y[p++] = i;
    31         for(i = 0; i < n; ++i) if(sa[i] >= k) y[p++] = sa[i] - k;
    32         for(i = 0; i < n; ++i) wv[i] = x[y[i]];
    33 
    34         for(i = 0; i < m; ++i) wd[i] = 0;
    35         for(i = 0; i < n; ++i) wd[wv[i]]++;
    36         for(i = 1; i < m; ++i) wd[i] += wd[i-1];
    37         for(i = n-1; i >= 0; --i) sa[--wd[wv[i]]] = y[i];
    38 
    39         swap(x,y);
    40         x[sa[0]] = 0;
    41         for(p = i = 1; i < n; ++i)
    42             x[sa[i]] = cmp(y,sa[i-1],sa[i],k)?p-1:p++;
    43     }
    44 }
    45 void calcp(int *r,int *sa,int n){
    46     for(int i = 1; i <= n; ++i) rk[sa[i]] = i;
    47     int h = 0;
    48     for(int i = 0; i < n; ++i){
    49         if(h > 0) h--;
    50         for(int j = sa[rk[i]-1]; i+h < n && j+h < n; h++)
    51             if(r[i+h] != r[j+h]) break;
    52         lcp[rk[i]-1] = h;
    53     }
    54 }
    55 int r[maxn],sa[maxn];
    56 char str[maxn];
    57 int main() {
    58     int n;
    59     scanf("%d",&n);
    60     while(n--){
    61         scanf("%s",str);
    62         int len = strlen(str);
    63         for(int i = 0; i < len; ++i)
    64             r[i] = str[i];
    65         r[len] = 0;
    66         da(r,sa,len+1,128);
    67         calcp(r,sa,len);
    68         int ans = 0;
    69         for(int i = 1; i <= len; ++i)
    70             ans += len - sa[i] - lcp[i];
    71         printf("%d
    ",ans);
    72     }
    73     return 0;
    74 }
    View Code

    后缀自动机

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 const int maxn = 100010;
     4 char str[maxn];
     5 int ret,n;
     6 struct SAM{
     7     struct node{
     8         int son[26],f,len;
     9         void init(){
    10             f = -1;
    11             len = 0;
    12             memset(son,-1,sizeof son);
    13         }
    14     }e[maxn];
    15     int tot,last;
    16     int newnode(int len = 0){
    17         e[tot].init();
    18         e[tot].len = len;
    19         return tot++;
    20     }
    21     void init(){
    22         tot = last = 0;
    23         newnode();
    24     }
    25     void extend(int c){
    26         int p = last,np = newnode(e[p].len + 1);
    27         while(p != -1 && e[p].son[c] == -1){
    28             e[p].son[c] = np;
    29             p = e[p].f;
    30         }
    31         if(p == -1) e[np].f = 0;
    32         else{
    33             int q = e[p].son[c];
    34             if(e[p].len + 1 == e[q].len) e[np].f = q;
    35             else{
    36                 int nq = newnode();
    37                 e[nq] = e[q];
    38                 e[nq].len = e[p].len + 1;
    39                 e[q].f = e[np].f = nq;
    40                 while(p != -1 && e[p].son[c] == q){
    41                     e[p].son[c] = nq;
    42                     p = e[p].f;
    43                 }
    44             }
    45         }
    46         last = np;
    47     }
    48     void solve(){
    49         ret = 0;
    50         for(int i = 1; i < tot; ++i)
    51             ret += e[i].len - e[e[i].f].len;
    52         printf("%d
    ",ret);
    53     }
    54 }sam;
    55 
    56 int main(){
    57     int kase;
    58     scanf("%d",&kase);
    59     while(kase--){
    60         scanf("%s",str);
    61         n = strlen(str);
    62         sam.init();
    63         for(int i = ret = 0; str[i]; ++i)
    64             sam.extend(str[i]-'A');
    65         sam.solve();
    66     }
    67     return 0;
    68 }
    View Code
  • 相关阅读:
    elasticsearch 中的Multi Match Query
    activiti 流程部署的各种方式
    elasticsearch 嵌套对象之嵌套类型
    elasticsearch Java High Level REST 相关操作封装
    elasticsearch 字段数据类型
    ubuntu 安装 docker
    elasticsearch 通过HTTP RESTful API 操作数据
    facenet 人脸识别(二)——创建人脸库搭建人脸识别系统
    POJ 3093 Margaritas(Kind of wine) on the River Walk (背包方案统计)
    墨卡托投影, GPS 坐标转像素, GPS 坐标转距离
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4033744.html
Copyright © 2011-2022 走看看