真是一道良好的SA模板题

首先,由于涉及到从左边移动到右边这个过程,我们不妨直接把字符串复制一遍,接在后面。

然后直接构造后缀数组,按排名从小到大,枚举所有的位置,如果这个后缀的起始点是在原串中的,那么就输出当前后缀的起始点往后第n个字符,就能直接解决了

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<queue>
  7. #include<map>
  8. #include<set>
  9. #define mk makr_pair
  10. #define ll long long
  11. using namespace std;
  12. inline int read()
  13. {
  14. int x=0,f=1;char ch=getchar();
  15. while (!isdigit(ch)) {if (ch=='-') f=-1;ch=getchar();}
  16. while (isdigit(ch)) {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
  17. return x*f;
  18. }
  19. const int maxn = 2e6+1e2;
  20. int rk[maxn],wb[maxn],sa[maxn];
  21. int tmp[maxn],h[maxn],height[maxn];
  22. int n;
  23. char a[maxn];
  24. void getsa()
  25. {
  26. int *x =rk,*y=tmp;
  27. int s = 128;
  28. for (int i=1;i<=n;i++) x[i]=a[i],y[i]=i;
  29. for (int i=1;i<=s;i++) wb[i]=0;
  30. for (int i=1;i<=n;i++) wb[x[y[i]]]++;
  31. for (int i=1;i<=s;i++) wb[i]+=wb[i-1];
  32. for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i];
  33. int p =0;
  34. for (int j=1;p<n;j<<=1)
  35. {
  36. p=0;
  37. for (int i=n-j+1;i<=n;i++) y[++p]=i;
  38. for (int i=1;i<=n;i++) if (sa[i]>j) y[++p] = sa[i]-j;
  39. for (int i=1;i<=s;i++) wb[i]=0;
  40. for (int i=1;i<=n;i++) wb[x[y[i]]]++;
  41. for (int i=1;i<=s;i++) wb[i]+=wb[i-1];
  42. for (int i=n;i>=1;i--) sa[wb[x[y[i]]]--]=y[i];
  43. swap(x,y);
  44. p=1;
  45. x[sa[1]]=1;
  46. for (int i=2;i<=n;i++)
  47. {
  48. x[sa[i]] = (y[sa[i]]==y[sa[i-1]] && y[sa[i]+j]==y[sa[i-1]+j]) ? p : ++p;
  49. }
  50. s=p;
  51. }
  52. for (int i=1;i<=n;i++) rk[sa[i]]=i;
  53. h[0]=0;
  54. for (int i=1;i<=n;i++)
  55. {
  56. h[i]=max(h[i-1]-1,0);
  57. while(i+h[i]<=n && sa[rk[i]-1]+h[i]<=n && a[i+h[i]]==a[sa[rk[i]-1]+h[i]]) h[i]++;
  58. }
  59. for (int i=1;i<=n;i++) height[i]=h[sa[i]];
  60. }
  61. int main()
  62. {
  63. scanf("%s",a+1);
  64. n=strlen(a+1);
  65. for (int i=1;i<=n;i++) a[i+n]=a[i];
  66. n*=2;
  67. getsa();
  68. for (int i=1;i<=n;i++)
  69. {
  70. if (sa[i]<=n/2) cout<<a[sa[i]+n/2-1];
  71. }
  72. return 0;
  73. }

洛谷4051 JSOI2007 字符加密(SA)的更多相关文章

  1. 洛谷 4051 [JSOI2007]字符加密(后缀数组)

    题目描述 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法. 例如‘JSOI07’,可以读作 ...

  2. 洛谷P4051 [JSOI2007]字符加密 后缀数组

    题目链接:https://www.luogu.org/problemnew/show/P4051 思路:我们联想求后缀数组sa的过程,发现我们在求y数组的时候(第二关键字,下标为第二关键字的排位,值为 ...

  3. 洛谷P4051 [JSOI2007]字符加密

    题目描述 喜欢钻研问题的JS 同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法:把需要加密的信息排成一圈,显然,它们有很多种不同的读法. 例如‘JSOI07’,可以读作 ...

  4. [JSOI2007]字符加密Cipher SA

    [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 7859  Solved: 3410[Submit][Stat ...

  5. BZOJ 1031: [JSOI2007]字符加密Cipher 后缀数组

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 6014  Solved: 2503[Submit ...

  6. bzoj 1031: [JSOI2007]字符加密Cipher 後綴數組模板題

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 3157  Solved: 1233[Submit ...

  7. 【BZOJ1031】[JSOI2007]字符加密Cipher 后缀数组

    [BZOJ1031][JSOI2007]字符加密Cipher Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把需要加密的 ...

  8. 1031: [JSOI2007]字符加密Cipher

    1031: [JSOI2007]字符加密Cipher Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 7338  Solved: 3182[Submit ...

  9. BZOJ_1031_[JSOI2007]字符加密Cipher_后缀数组

    BZOJ_1031_[JSOI2007]字符加密Cipher_后缀数组 Description 喜欢钻研问题的JS同学,最近又迷上了对加密方法的思考.一天,他突然想出了一种他认为是终极的加密办法 :把 ...

随机推荐

  1. Tensorflow 2.0 深度学习实战 —— 详细介绍损失函数、优化器、激活函数、多层感知机的实现原理

    前言 AI 人工智能包含了机器学习与深度学习,在前几篇文章曾经介绍过机器学习的基础知识,包括了监督学习和无监督学习,有兴趣的朋友可以阅读< Python 机器学习实战 >.而深度学习开始只 ...

  2. MutationObserver API

    1.概述 MutationObserver接口提供了监视对DOM树所做更改的能力.它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分. 但是,它与Mu ...

  3. 安装配置Linux Squid代理服务器

    1.代理服务器的工作机制 代理服务器的工作机制像生活中的代理商,假设自己的机器为A,想获得的数据由服务器B提供,代理服务器为C,那么连接过程是,A需要B的数据,并直接和C连接:C接受到A的数据请求之后 ...

  4. tomcat配置启动不了

    关于ideatomcat配置问题 1.第一步配置tomcat启动器 2.配置启动的网址 3.配置启动器的启动 ---更多java学习,请见本人小博客:https://zhangjzm.gitee.io ...

  5. Spring Security进阶

    Spring Security进阶 1.连接数据库进行数据的验证 Spring Security进行身份验证或者权限控制时,用户名和密码应该要和数据库的进行比较才行,用户的各种信息我们从数据库中去获取 ...

  6. client-go实战之三:Clientset

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  7. Python 高级特性(5)- 迭代器 Iterator

    前言 迭代器貌似是 Python3 才有的(猜的),在廖雪峰大神的网站中 Python2 是没有迭代器一栏的 可 for 循环的对象 常见集合数据类型(迭代对象):list.tuple.dict.se ...

  8. kubectl apply部署时可以用 --record 方便记录版本 和回退

    1.部署时正常时下面的 kubectl apply -f http.yaml 2.如果修改文件文件重新部署或者之前有上一个版本的  想回退上一个的 可以无感知的回退回去 不影响业务 其中http-de ...

  9. 第七章:网络优化与正则化(Part2)

    文章相关 1 第七章:网络优化与正则化(Part1) 2 第七章:网络优化与正则化(Part2) 7.3 参数初始化 神经网络的参数学习是一个非凸优化问题.当使用梯度下降法来进行优化网络参数时,参数初 ...

  10. PHP出现iconv(): Detected an illegal character in input string

    PHP传给JS字符串用ecsape转换加到url里,又用PHP接收,再用网上找的unscape函数转换一下,这样得到的字符串是UTF-8的,但我需要的是GB2312,于是用iconv转换 开始是这样用 ...