• poj3581 Sequence (后缀数组)


    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 6305   Accepted: 1364
    Case Time Limit: 2000MS

    Description

    Given a sequence, {A1A2, ..., An} which is guaranteed AA2, ..., An,  you are to cut it into three sub-sequences and reverse them separately to form a new one which is the smallest possible sequence in alphabet order.

    The alphabet order is defined as follows: for two sequence {A1A2, ..., An} and {B1B2, ..., Bn}, we say {A1A2, ..., An} is smaller than {B1B2, ..., Bn} if and only if there exists such i ( 1 ≤ i ≤ n) so that we have Ai < Bi and Aj = Bj for each j < i.

    Input

    The first line contains n. (n ≤ 200000)

    The following n lines contain the sequence.

    Output

    output n lines which is the smallest possible sequence obtained.

    Sample Input

    5
    10
    1
    2
    3
    4
    

    Sample Output

    1
    10
    2
    4
    3
    

    Hint

    {10, 1, 2, 3, 4} -> {10, 1 | 2 | 3, 4} -> {1, 10, 2, 4, 3}


    题意:给你n个数(保证第一个数字大于这n个数的其他任何数字),让你把这n个数分成三份,每一份必须至少含有一个数字,然后把这三份的数字倒置,再把这三部分拼成一个串,并且要使得这个字符串的字典序最小。

    思路:先考虑第一段,因为第一个数字大于这n个数的其他任何数字,所以我们可以把字符串取反,然后找到字典序最小的后缀作为第一段,还要保证后缀的长度不超过n-2,如果超过后面就不能分成两个串(如果这里不懂可以画一下).然后我们把剩下的字符串取出来,表示成长度为m的a[]数组,接下来的问题就变为怎么样找到一个分割点k,使得a[0],a[1],...a[k]的反串和a[k+1],a[k+2]...a[m-1]的反串连接起来的串的字典序最小,我们转化一下就变为求分割点k,使得a[k],a[k-1]...a[0],a[m-1],a[m-2]...a[k+1]的字典序最小,我们发现,a[k],a[k-1]...a[0],a[m-1],a[m-2]...a[k+1]是a[m-1]...a[0]a[m-1]...a[0]的子串,所以我们只要把串a反一下,然后再扩展一倍,求出最小字典序的后缀就行了,这里要注意后缀的起始位置要大于0,小于m。

    ps:这题不能用多组数据输入,会wa,也是醉了。


    #include<iostream>
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<vector>
    #include<map>
    #include<set>
    #include<string>
    #include<bitset>
    #include<algorithm>
    using namespace std;
    #define lson th<<1
    #define rson th<<1|1
    typedef long long ll;
    typedef long double ldb;
    #define inf 99999999
    #define pi acos(-1.0)
    #define maxn 400050
    int sa[maxn],a[maxn],b[maxn],pos[maxn];
    int wa[maxn],wb[maxn],wv[maxn],we[maxn];
    int rk[maxn],height[maxn];
    int cmp(int *r,int a,int b,int l){
        return r[a]==r[b]&&r[a+l]==r[b+l];
    }
    void build_sa(int *r,int n,int m)
    {
        int i,j,p,*x=wa,*y=wb,*t;
        for(i=0;i<m;i++)we[i]=0;
        for(i=0;i<n;i++)we[x[i]=r[i]]++;
        for(i=1;i<m;i++)we[i]+=we[i-1];
        for(i=n-1;i>=0;i--)sa[--we[x[i]]]=i;
        for(j=1,p=1;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++)we[i]=0;
            for(i=0;i<n;i++)we[wv[i]]++;
            for(i=1;i<m;i++)we[i]+=we[i-1];
            for(i=n-1;i>=0;i--)sa[--we[wv[i]]]=y[i];
            for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++)
            x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
        }
    }
    
    void calheight(int *r,int n)
    {
        int i,j,k=0;
        for(i=1;i<=n;i++)rk[sa[i]]=i;
        for(i=0;i<n;height[rk[i++] ]=k){
            for(k?k--:0,j=sa[rk[i]-1];r[i+k]==r[j+k];k++);
        }
    }
    
    int calmin(int n)
    {
        int minx=inf,i;
        int weizhi=-1;
        for(i=2;i<n;i++){
            if(rk[i]<minx){
                minx=rk[i];
                weizhi=i;
            }
        }
        return weizhi;
    }
    int c[maxn],cnt;
    int d[maxn];
    
    int main()
    {
        int m,i,j,tot,n,weizhi,mm;
        scanf("%d",&n);
        tot=0;
        for(i=0;i<n;i++){
            scanf("%d",&a[i]);
            pos[++tot]=a[i];
        }
        sort(pos+1,pos+1+tot);
        tot=unique(pos+1,pos+1+tot)-pos-1;
    
        for(i=0;i<n;i++){
            a[i]=lower_bound(pos+1,pos+1+tot,a[i])-pos;
            b[n-1-i]=a[i];
        }
        b[n]=0;
        build_sa(b,n+1,200010);
        calheight(b,n);
        weizhi=calmin(n);
    
        cnt=0;
        for(i=weizhi;i<n;i++){
            c[cnt++]=pos[b[i] ];
        }
    
        m=0;
        for(i=0;i<weizhi;i++){
            d[m++]=b[i];
        }
        for(i=0;i<m;i++){
            d[i+m]=d[i];
        }
        mm=m*2;
    
        d[mm]=0;
        build_sa(d,mm+1,200010 );
        calheight(d,mm);
    
        int minx=inf;
        weizhi=-1;
        for(i=1;i<m;i++){
            if(rk[i]<minx){
                minx=rk[i];
                weizhi=i;
            }
        }
        for(i=weizhi;i<m;i++){
            c[cnt++]=pos[d[i] ];
        }
        for(i=0;i<weizhi;i++){
            c[cnt++]=pos[d[i] ];
        }
    
        for(i=0;i<cnt;i++){
            printf("%d
    ",c[i]);
        }
    }


  • 相关阅读:
    第3章 机器学习的典型应用 3-2 典型应用-聚类
    第3章 机器学习的典型应用 3-1 典型应用-关联规则
    6-13 Hog特征1
    6-12 SVM小结
    Linux中常见的环境变量笔记
    Linux中常见的环境变量笔记
    Linux中shell变量基础概念笔记
    Linux中shell变量基础概念笔记
    Linux常用内建命令笔记
    Linux常用内建命令笔记
  • 原文地址:https://www.cnblogs.com/herumw/p/9464487.html
Copyright © 2020-2023  润新知