• acdream 1430 SETI 后缀数组+height分组


    这题昨天比赛的时候逗了,后缀想不出来,由于n^2的T了,就没往后缀数组想……并且之后解题的人又说用二分套二分来做。然后就更不会了……

    刚才看了题解,唉……原来题讲解n^2的也能够过,然后就……这样了!

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<queue>
    #include<set>
    #include<cmath>
    #include<bitset>
    #define mem(a,b) memset(a,b,sizeof(a))
    #define lson i<<1,l,mid
    #define rson i<<1|1,mid+1,r
    #define llson j<<1,l,mid
    #define rrson j<<1|1,mid+1,r
    #define INF 0x7fffffff
    #define seed 13131
    #define seed1 1313
    #define maxn 20005
    typedef long long ll;
    typedef unsigned long long ull;
    using namespace std;
    void radix(int *str,int *a,int *b,int n,int m)
    {
        static int count[maxn];
        mem(count,0);
        for(int i=0; i<n; i++) ++count[str[a[i]]];
        for(int i=1; i<=m; i++) count[i]+=count[i-1];
        for(int i=n-1; i>=0; i--) b[--count[str[a[i]]]]=a[i];
    }
    void suffix(int *str,int *sa,int n,int m) //倍增算法计算出后缀数组sa
    {
        static int rank[maxn],a[maxn],b[maxn];
        for(int i=0; i<n; i++) rank[i]=i;
        radix(str,rank,sa,n,m);
        rank[sa[0]]=0;
        for(int i=1; i<n; i++)
            rank[sa[i]]=rank[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]);
        for(int i=0; 1<<i<n; i++)
        {
            for(int j=0; j<n; j++)
            {
                a[j]=rank[j]+1;
                b[j]=j+(1<<i)>=n?0:rank[j+(1<<i)]+1;
                sa[j]=j;
            }
            radix(b,sa,rank,n,n);
            radix(a,rank,sa,n,n);
            rank[sa[0]]=0;
            for(int j=1; j<n; j++)
                rank[sa[j]]=rank[sa[j-1]]+(a[sa[j-1]]!=a[sa[j]]||b[sa[j-1]]!=b[sa[j]]);
        }
    }
    void calcHeight(int *str,int *sa,int *h,int *rank,int n) //求出最长公共前缀数组h
    {
        int k=0;
        h[0]=0;
        for(int i=0; i<n; i++) rank[sa[i]]=i;
        for(int i=0; i<n; i++)
        {
            k=k==0?0:k-1;
            if(rank[i])
                while(str[i+k]==str[sa[rank[i]-1]+k]) k++;
            else k=0;
            h[rank[i]]=k;
        }
    }
    int a[maxn],sa[maxn],height[maxn],rank[maxn];
    char s[maxn];
    int main()
    {
        //freopen("1.txt","r",stdin);
        scanf("%s",s);
        int n=strlen(s);
        copy(s,s+n,a);
        suffix(a,sa,n,150);
        calcHeight(a,sa,height,rank,n);
        int Max,Min,sum=0;
        for(int i=1;i<=n/2;i++)
        {
            Max=Min=sa[0];
            for(int j=1;j<=n;j++)
            {
                if(height[j]<i||j==n)
                {
                    if(Max-Min>=i) sum++;
                    Max=Min=sa[j];
                }
                else
                {
                    Max=max(Max,sa[j]);
                    Min=min(Min,sa[j]);
                }
            }
        }
        printf("%d
    ",sum);
        return 0;
    }
    


  • 相关阅读:
    Linux驱动入门(三)Led驱动
    Linux驱动入门(二)操作硬件
    mysql表的完整性约束
    数据库操作
    初识数据库
    mysql的安装、启动和基础配置 —— windows版本
    Socket网络编程
    python进阶之多线程(简单介绍协程)
    python进阶多进程(进程池,进程间通信)
    python基础之异常处理
  • 原文地址:https://www.cnblogs.com/llguanli/p/7359107.html
Copyright © 2020-2023  润新知