zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    POJ1470 Closest Common Ancestors(LCA入门)
    POJ1330 Nearest Common Ancestors(倍增LCA算法求无边权树的模板)
    HDU3078 Network (倍增LCA算法求树链)
    HDU2874 Connections between cities(并查集+倍增LCA算法求森林最短路)
    HDU2586 How far away?(倍增LCA算法求带边权树上最短路)
    POJ1062 昂贵的聘礼
    HDU4725 The Shortest Path in Nya Graph(堆优化的dijkstra算法)
    数据仓库详解:包括概念、架构及设计
    利用行为标签构建用户画像
    Spark SQL深度理解篇:模块实现、代码结构及执行流程总览(2)
  • 原文地址:https://www.cnblogs.com/fzf123/p/3063570.html
Copyright © 2011-2022 走看看