• hdu 3518 Boring counting(后缀数组+height分组)


    题意:求重复但不重叠的子串数。

    解题思路:height分组。枚举长度L,将height数组进行分组,使得每一组的height都大于L,若有一组的最大的sa值和最小的sa值之差大于L,则说明该组内存在一个符合条件的子串。

    View Code
      1 /*
      2  *Author:       Zhaofa Fang
      3  *Created time: 2013-05-06-19.28
      4  *Language:     C++
      5  */
      6 #include <cstdio>
      7 #include <cstdlib>
      8 #include <sstream>
      9 #include <iostream>
     10 #include <cmath>
     11 #include <cstring>
     12 #include <algorithm>
     13 #include <string>
     14 #include <utility>
     15 #include <vector>
     16 #include <queue>
     17 #include <map>
     18 #include <set>
     19 using namespace std;
     20 
     21 typedef long long ll;
     22 #define DEBUG(x) cout<< #x << ':' << x << endl
     23 #define FOR(i,s,t) for(int i = (s);i <= (t);i++)
     24 #define FORD(i,s,t) for(int i = (s);i >= (t);i--)
     25 #define REP(i,n) for(int i=0;i<n;i++)
     26 #define REPD(i,n) for(int i=n-1;i>=0;i--)
     27 #define PII pair<int,int>
     28 #define PB push_back
     29 #define MP make_pair
     30 #define ft first
     31 #define sd second
     32 #define lowbit(x) (x&(-x))
     33 #define INF (1<<30)
     34 
     35 
     36 const int maxn = 1011;
     37 char s[maxn];
     38 int sa[maxn],t1[maxn],t2[maxn],c[maxn];
     39 int rank[maxn],height[maxn];
     40 
     41 void getHeight(int n){
     42     int k = 0;
     43     for(int i=1;i<=n;i++)rank[sa[i]] = i;
     44     for(int i=0;i<n;i++){
     45         if(k)k--;
     46         int j = sa[rank[i]-1];
     47         while(s[i+k] == s[j+k])k++;
     48         height[rank[i]] = k;
     49     }
     50 }
     51 bool cmp(int *r,int a,int b,int l){
     52     return (r[a] == r[b] && r[a+l]==r[b+l]);
     53 }
     54 void build_sa(int m,int n){
     55     int i,*x=t1,*y=t2,k,p;
     56     for( i=0;i<m;i++)c[i] = 0;
     57     for( i=0;i<n;i++)c[x[i]=s[i]] ++;
     58     for( i=1;i<m;i++)c[i] += c[i-1];
     59     for( i=n-1;i>=0;i--)sa[-- c[x[i]]] = i;
     60     for(k=1,p=0;p<n;m=p,k<<=1){
     61         p=0;
     62         for(i=n-k;i<n;i++)y[p++] = i;
     63         for(i=0;i<n;i++)if(sa[i]>=k)y[p++] = sa[i]-k;
     64         for(i=0;i<m;i++)c[i] = 0;
     65         for(i=0;i<n;i++)c[x[y[i]]] ++;
     66         for(i=1;i<m;i++)c[i] += c[i-1];
     67         for(i=n-1;i>=0;i--)sa[-- c[x[y[i]]]] = y[i];
     68         swap(x,y);
     69         p = 1; x[sa[0]] = 0;
     70         for(i=1;i<n;i++)
     71             x[sa[i]] = cmp(y,sa[i-1],sa[i],k)?p-1:p++;
     72     }
     73     getHeight(n-1);
     74 }
     75 int solve(int n){
     76     int ans = 0;
     77     for(int i=1;i<=n/2;i++){
     78         int mi = sa[1],mx = sa[1];
     79         for(int j=2;j<=n+1;j++){
     80             if(j!=n+1 && height[j]>=i){
     81                 mi = min(mi,sa[j]);
     82                 mx = max(mx,sa[j]);
     83             }else {
     84                 if(mx - mi >= i)ans++;
     85                 mx = mi = sa[j];
     86             }
     87         }
     88     }
     89     return ans;
     90 }
     91 int main(){
     92     //freopen("in","r",stdin);
     93     //freopen("out","w",stdout);
     94     while(gets(s)){
     95         if(s[0] == '#')break;
     96         int n = strlen(s);
     97         REP(i,n)s[i] = s[i] - 'a' + 1;
     98         build_sa(28,n+1);
     99         printf("%d\n",solve(n));
    100     }
    101     return 0;
    102 }
    by Farmer
  • 相关阅读:
    你所不知道的React Hooks
    DataRow的RowState属性变化
    gRPC详解
    Protobuf简明教程
    docker容器内没有权限
    Locust高并发情况下的性能优化与分布式场景的应用
    Docker容器日志打满机器的解决方式
    Django单测详解
    使用Flask+uwsgi+Nginx部署Flask正式环境
    Locust-分布式执行
  • 原文地址:https://www.cnblogs.com/fzf123/p/3063570.html
Copyright © 2020-2023  润新知