• p4051 [JSOI2007]字符加密


    传送门

    分析

    将字符串复制一遍然后直接求sa即可

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<cctype>
    #include<cmath>
    #include<cstdlib>
    #include<ctime>
    #include<queue>
    #include<vector>
    #include<set>
    #include<map>
    #include<stack>
    using namespace std;
    char s[200100];
    int n,m=128,rk[200100],sa[200100],tax[200100],tp[200100],h[200100],height[200100];
    inline void qsort(){
        for(int i=0;i<=m;i++)tax[i]=0;
        for(int i=1;i<=n;i++)tax[rk[i]]++;
        for(int i=1;i<=m;i++)tax[i]+=tax[i-1];
        for(int i=n;i>0;i--)sa[tax[rk[tp[i]]]--]=tp[i];
    }
    inline void work(){
        for(int i=1;i<=n;i++)rk[i]=s[i]-'0'+1,tp[i]=i;qsort();
        for(int w=1,p=0;p<n;m=p,w<<=1){
          p=0;for(int i=1;i<=w;i++)tp[++p]=n-w+i;
          for(int i=1;i<=n;i++)if(sa[i]>w)tp[++p]=sa[i]-w;
          qsort();swap(rk,tp);rk[sa[1]]=p=1;
          for(int i=2;i<=n;i++)rk[sa[i]]=(tp[sa[i-1]]==tp[sa[i]]&&tp[sa[i-1]+w]==tp[sa[i]+w])?p:++p;
        }
        for(int i=1;i<=n;i++)rk[sa[i]]=i;h[0]=0;
        for(int i=1;i<=n;i++){
          h[i]=max(h[i-1]-1,0);
          while(i+h[i]<=n&&sa[rk[i]-1]<=n&&s[i+h[i]]==s[sa[rk[i]-1]+h[i]])h[i]++;
        }
        for(int i=1;i<=n;i++)height[i]=h[sa[i]];
    }
    int main(){
        scanf("%s",s+1);n=strlen(s+1);for(int i=1;i<=n;i++)s[i+n]=s[i];
        n<<=1;work();for(int i=1;i<=n;i++)if(sa[i]<=n/2)cout<<s[sa[i]+n/2-1];
        return 0;
    }
  • 相关阅读:
    数据结构进阶——线段树
    基本数据结构—Hash哈希
    NOIP2013提高组 day2 2019.7.15
    基本算法——归并排序
    基本数据结构—Trie
    NOIP 2011 提高组 Day2 校模拟 7.11
    Noip2014提高组真题Day1,2 校模拟7.7
    NOIP2015 提高组 day1 7.8校模拟
    NOIP2008 提高组 6.9校模拟
    STL-#include<set>
  • 原文地址:https://www.cnblogs.com/yzxverygood/p/10605942.html
Copyright © 2020-2023  润新知