zoukankan      html  css  js  c++  java
  • 洛谷P2870

    Portal

    Description

    给出一个字符串(s(|s|leq3 imes10^4)),每次从(s)的开头或结尾取出一个字符接在新字符串(s')的末尾。求字典序最小的(s')

    Solution

    设当前剩余的字符串为(t),将其翻转得到(t')。则(t<t')时取开头,否则取结尾。
    (p=lcp(t,t')),则有(t<t' Leftrightarrow t[1..p]=t'[1..p],t[p+1]<t'[p+1])。那么最优的取法必然是依次取完(t[1..p]),也就是取开头。
    s+'#'+rev(s)求后缀数组,那么可以将前半部分的后缀视为(t),后半部分的后缀视为(t'),比较(rnk)来决定取哪边。

    时间复杂度(O(nlogn))

    Code

    //[USACO07DEC]最佳牛线Best Cow Line
    #include <cstdio>
    #include <cstring>
    int const N=6e4+10;
    int n0,n; char s[N];
    int sa[N],rnk[N<<1];
    int cnt[N],tmp[N],rnk1[N<<1];
    void getSA()
    {
        for(int i=1;i<=n;i++) cnt[s[i]]=1;
        for(int i=1;i<=256;i++) cnt[i]+=cnt[i-1];
        for(int i=1;i<=n;i++) rnk[i]=cnt[s[i]];
        for(int L=1,k=0;k<n;L<<=1)
        {
            memset(cnt,0,sizeof cnt);
            for(int i=1;i<=n;i++) cnt[rnk[i+L]]++;
            for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;i--) tmp[cnt[rnk[i+L]]--]=i;
            memset(cnt,0,sizeof cnt);
            for(int i=1;i<=n;i++) cnt[rnk[tmp[i]]]++;
            for(int i=1;i<=n;i++) cnt[i]+=cnt[i-1];
            for(int i=n;i>=1;i--) sa[cnt[rnk[tmp[i]]]--]=tmp[i];
            k=0; memcpy(rnk1,rnk,sizeof rnk);
            for(int i=1;i<=n;i++)
            {
                if(rnk1[sa[i]]!=rnk1[sa[i-1]]||rnk1[sa[i]+L]!=rnk1[sa[i-1]+L]) k++;
                rnk[sa[i]]=k;
            }
        }
    }
    int main()
    {
        scanf("%d",&n0); n=n0+n0+1;
        for(int i=1;i<=n0;i++) {char ch[5]; scanf("%s",ch),s[i]=ch[0];}
        s[n0+1]='#'; for(int i=1;i<=n0;i++) s[n-i+1]=s[i]; //puts(s+1);
        getSA();
        int L=1,R=n0+2;
        for(int i=1;i<=n0;i++)
        {
            printf("%c",rnk[L]<rnk[R]?s[L++]:s[R++]);
            if(i%80==0) puts("");
        }
        puts("");
        return 0;
    }
    

    P.S.

    输出要求80个字符一行。

  • 相关阅读:
    编译并使用Lua语言
    C#中使用DLL文件
    将Unity3D游戏移植到Android平台上
    Unity3D知识点
    清下书柜,工作书,旧书,正版书,个人学习过的书asp,net,delphi,java,flex,actionscript,vb...
    使用ABP打造SAAS系统(2)——前端框架选择
    使用ABP打造SAAS系统(1)——环境准备
    延迟实例单例模式注意点
    jvm指令解释i = i++ + i++ + i++ + ++i;等于多少
    MYSQL增加库表权限
  • 原文地址:https://www.cnblogs.com/VisJiao/p/LgP2870.html
Copyright © 2011-2022 走看看