zoukankan      html  css  js  c++  java
  • CSU1656: Paper of FlyBrother(后缀数组)

    Description

    FlyBrother is a superman, therefore he is always busy saving the world. 
    To graduate from NUDT is boring but necessary for him. Typically We need to post an paper to get Graduate Certificate, however being one superman, FlyBrother wants to make his paper perfect. A paper is a lower case string. To make it perfect, FlyBrother wanna the number of different substrings in the paper. It is quite a silly problem for FlyBrother, but because he is so busy, can you help him to solve it?

    Input

    There are several cases. Process till EOF.
    For each case, there is a line of lower case string (1<=length<=100000).

    Output

    For each case, output one number in a line of the answer described in the problem.

    Sample Input

    a
    aab
    

    Sample Output

    1
    5
    

    HINT


    题意:
    求不同的字符串个数

    思路:
    在我的后缀数组题目小结里有一样的的题目。模板题

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <stack>
    #include <queue>
    #include <map>
    #include <set>
    #include <vector>
    #include <math.h>
    #include <bitset>
    #include <algorithm>
    #include <climits>
    using namespace std;
    
    #define LS 2*i
    #define RS 2*i+1
    #define UP(i,x,y) for(i=x;i<=y;i++)
    #define DOWN(i,x,y) for(i=x;i>=y;i--)
    #define MEM(a,x) memset(a,x,sizeof(a))
    #define W(a) while(a)
    #define gcd(a,b) __gcd(a,b)
    #define LL long long
    #define N 100005
    #define MOD 1000000007
    #define INF 0x3f3f3f3f
    #define EXP 1e-8
    LL wa[N],wb[N],wsf[N],wv[N],sa[N];
    LL rank1[N],height[N],s[N],a[N];
    char str[N],str1[N],str2[N];
    //sa:字典序中排第i位的起始位置在str中第sa[i]
    //rank:就是str第i个位置的后缀是在字典序排第几
    //height:字典序排i和i-1的后缀的最长公共前缀
    LL cmp(LL *r,LL a,LL b,LL k)
    {
        return r[a]==r[b]&&r[a+k]==r[b+k];
    }
    void getsa(LL *r,LL *sa,LL n,LL m)//n要包括末尾加入的0
    {
        LL i,j,p,*x=wa,*y=wb,*t;
        for(i=0; i<m; i++)  wsf[i]=0;
        for(i=0; i<n; i++)  wsf[x[i]=r[i]]++;
        for(i=1; i<m; i++)  wsf[i]+=wsf[i-1];
        for(i=n-1; i>=0; i--)  sa[--wsf[x[i]]]=i;
        p=1;
        j=1;
        for(; p<n; j*=2,m=p)
        {
            for(p=0,i=n-j; i<n; i++)  y[p++]=i;
            for(i=0; i<n; i++)  if(sa[i]>=j)  y[p++]=sa[i]-j;
            for(i=0; i<n; i++)  wv[i]=x[y[i]];
            for(i=0; i<m; i++)  wsf[i]=0;
            for(i=0; i<n; i++)  wsf[wv[i]]++;
            for(i=1; i<m; i++)  wsf[i]+=wsf[i-1];
            for(i=n-1; i>=0; i--)  sa[--wsf[wv[i]]]=y[i];
            t=x;
            x=y;
            y=t;
            x[sa[0]]=0;
            for(p=1,i=1; i<n; i++)
                x[sa[i]]=cmp(y,sa[i-1],sa[i],j)? p-1:p++;
        }
    }
    void getheight(LL *r,LL n)//n不保存最后的0
    {
        LL i,j,k=0;
        for(i=1; i<=n; i++)  rank1[sa[i]]=i;
        for(i=0; i<n; i++)
        {
            if(k)
                k--;
            else
                k=0;
            j=sa[rank1[i]-1];
            while(r[i+k]==r[j+k])
                k++;
            height[rank1[i]]=k;
        }
    }
    LL t,ans,n,m;
    
    int main()
    {
        LL i,j,k,len;
        W(~scanf("%s",str))
        {
            len = strlen(str);
            UP(i,0,len-1)
            s[i]=str[i];
            s[len] = 0;
            getsa(s,sa,len+1,300);
            getheight(s,len);
            ans = (1+len)*len/2;
            UP(i,2,len)
            ans-=height[i];
            printf("%lld
    ",ans);
        }
    }
    


  • 相关阅读:
    面试问题整理Andorid版本 date: 2017-1-12 21:14:36 categories: 技术
    轻量级的C++插件框架
    C++程序在Windows平台上各种定位内存泄漏的方法,并对比了它们的优缺点
    Facebook App 的头文件会有更多的收获
    合并Excel工作薄中成绩表的VBA代码,非常适合教育一线的朋友_python
    使用python在校内发人人网状态(人人网看状态)_python
    使用PYTHON创建XML文档_python
    优秀的缓存请求库,快速请求接口和图片:WTRequestCenter
    让读者快速了解RocketMQ消息中间件需要解决哪些问题
    编绎调试HotSpot JVM及在Eclipse里调试HotSpot一些步骤
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/8331217.html
Copyright © 2011-2022 走看看