zoukankan      html  css  js  c++  java
  • csu 1305 Substring (后缀数组)

    http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1305

    1305: Substring

    Time Limit: 2 Sec  Memory Limit: 10 MB Submit: 12  Solved: 2 [Submit][Status][Web Board]

    Description

    Given a string s. The length of s is smaller than 1000. You are to caculate the number of different substrings of s.

    Input

    There are multiple test cases. Each test case contains one line, with a string s.You may assume that s only contains lowercase letters. You may assume that there are only ten test cases with the length of string s is bigger than 400.

    Output

    For each test case, you are only to output one integer,  the answer.

    Sample Input

    a
    ac
    abcd

    Sample Output

    1
    3
    10
    

    【题解】:
    后缀数组:用(1+2+。。。+len)-(height数组之后)
    【code】:
     1 #include <iostream>
     2 #include<string.h>
     3 #include<stdio.h>
     4 
     5 using namespace std;
     6 
     7 #define maxn 10100
     8 #define cls(x) memset(x, 0, sizeof(x))
     9 int wa[maxn],wb[maxn],wv[maxn],wss[maxn];
    10 int cmp(int *r,int a,int b,int l)
    11 {return r[a]==r[b]&&r[a+l]==r[b+l];}
    12 
    13 void da(char *r,int *sa,int n,int m)
    14 {
    15      cls(wa);
    16      cls(wb);
    17      cls(wv);
    18      cls(wss);
    19      int i,j,p,*x=wa,*y=wb,*t;
    20      for(i=0;i<m;i++) wss[i]=0;
    21      for(i=0;i<n;i++) wss[x[i]=r[i]]++;
    22      for(i=1;i<m;i++) wss[i]+=wss[i-1];
    23      for(i=n-1;i>=0;i--) sa[--wss[x[i]]]=i;
    24      for(j=1,p=1;p<n;j*=2,m=p)
    25      {
    26        for(p=0,i=n-j;i<n;i++) y[p++]=i;
    27        for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
    28        for(i=0;i<n;i++) wv[i]=x[y[i]];
    29        for(i=0;i<m;i++) wss[i]=0;
    30        for(i=0;i<n;i++) wss[wv[i]]++;
    31        for(i=1;i<m;i++) wss[i]+=wss[i-1];
    32        for(i=n-1;i>=0;i--) sa[--wss[wv[i]]]=y[i];
    33        for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
    34        x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
    35      }
    36      return;
    37 }
    38 int rank[maxn],height[maxn];
    39 void calheight(char *r,int *sa,int n)
    40 {
    41      cls(rank);
    42      cls(height);
    43      int i,j,k=0;
    44      for(i=1;i<n;i++) rank[sa[i]]=i;
    45      for(i=0;i<n;height[rank[i++]]=k)
    46      for(k?k--:0,j=sa[rank[i]-1];r[i+k]==r[j+k]&&i!=j;k++);
    47      return;
    48 }
    49 
    50 char ca[maxn * 2];
    51 int sa[maxn];
    52 
    53 int main()
    54 {
    55     while (cin >> ca)
    56     {
    57         int len = strlen(ca);
    58         da(ca, sa, len+1, 130);
    59         calheight(ca,sa,len+1);
    60         int i,sum=0;
    61         for(i=1;i<=len;i++)
    62         {
    63             sum+=height[i];
    64         }
    65         cout<<len*(len+1)/2-sum<<endl;
    66         cls(ca);
    67     }
    68     return 0;
    69 }
  • 相关阅读:
    线程操作共享变量的一点分享。
    C调用栈重温
    8051汇编命令记录。
    没事写个散列玩~
    Ubuntu切换root用户权限
    CEdit自动换行和状态栏添加
    基于原始套接字的嗅探器
    Windows录音API学习笔记
    Windows内存管理
    C语言中tm结构体
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3293554.html
Copyright © 2011-2022 走看看