bzoj1031题解

【解题思路】

  将原串复制一份拼接到原串后作为处理串,可以对处理串的前一半后缀排序,即可得出顺序。复杂度O(Llog2L)。

【参考代码】

  也是naive的时候写的。。后缀数组居然是用桶排求的。。

 1 #pragma optimize(2)
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <vector>
 5 #define REP(I,start,end) for(int I=(start);I<=(end);I++)
 6 #define PER(I,start,end) for(int I=(start);I>=(end);I--)
 7 using namespace std;
 8 typedef vector<int> vecint;
 9 vecint srt[100010];
10 int suffix[100010],rank[100010],srnk[100010];
11 char st[100010];
12 int main()
13 {
14     scanf("%s",st);
15     int n=strlen(st);
16     memset(srt,0,sizeof(srt));
17     REP(i,1,n)
18         srt[st[i-1]].push_back(i);
19     int cnt=0,tot=0;
20     REP(i,0,255)
21         if(!srt[i].empty())
22         {
23             cnt++;
24             for(vecint::iterator it=srt[i].begin();it!=srt[i].end();it++)
25             {
26                 int now=*it;
27                 suffix[++tot]=now;
28                 rank[now]=cnt;
29             }
30         }
31     for(int i=1;i<n;i<<=1)
32     {
33         memset(srt,0,sizeof(srt));
34         REP(j,1,n)
35         {
36             int now=i+j;
37             now-=(now>n)*n;
38             srt[rank[now]].push_back(j);
39         }
40         tot=cnt=0;
41         REP(j,0,n)
42             if(!srt[j].empty())
43             {
44                 cnt++;
45                 for(vecint::iterator it=srt[j].begin();it!=srt[j].end();it++)
46                 {
47                     int now=*it;
48                     suffix[++tot]=now;
49                     srnk[now]=cnt;
50                 }
51             }
52         memset(srt,0,sizeof(srt));
53         REP(j,1,n)
54             srt[rank[suffix[j]]].push_back(suffix[j]);
55         cnt=tot=0;
56         REP(j,0,n)
57             if(!srt[j].empty())
58             {
59                 int last=-1;
60                 for(vecint::iterator it=srt[j].begin();it!=srt[j].end();it++)
61                 {
62                     int now=*it,pnt=srnk[now];
63                     cnt+=pnt>last;
64                     last=pnt;
65                     suffix[++tot]=now;
66                     rank[now]=cnt;
67                 }
68             }
69     }
70     REP(i,1,n)
71         putchar(st[(suffix[i]+n-2)%n]);
72     putchar(‘\n‘);
73     return 0;
74 }

时间: 2024-11-08 19:23:30

bzoj1031题解的相关文章

bzoj1031[JSOI2007]字符加密

bzoj1031[JSOI2007]字符加密 题意: 一种加密办法是把需要加密的信息排成一圈,显然,它们有很多种不同的读法.把它们按照字符串的大小排序,读出最后一列字符,就是加密后的字符串.给出原字符串,求加密后的字符串. 题解: 将原字符串重复后接在后面,然后求后缀数组,注意求完后要取那些长度大于原字符串长度a2的后缀的第a2个字符. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm>

洛谷 P1079 Vigen&#232;re 密码 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=1079 题目描述 16 世纪法国外交家 Blaise de Vigenère 设计了一种多表密码加密算法――Vigenère 密 码.Vigenère 密码的加密解密算法简单易用,且破译难度比较高,曾在美国南北战争中为 南军所广泛使用. 在密码学中,我们称需要加密的信息为明文,用 M 表示:称加密后的信息为密文,用 C 表示:而密钥是一种

8.8联考题解

今天的T1让我怀疑我是不是在做奥赛题--这考的是什么知识点啊这个,会不会用绝对值函数? Evensgn 的债务 时间限制: 1 Sec  内存限制: 128 MB 题目描述 Evensgn 有一群好朋友,他们经常互相借钱.假如说有三个好朋友A,B,C.A 欠 B 20 元,B 欠 C 20 元,总债务规模为 20+20=40 元.Evensgn 是个追求简约的人,他觉得这样的债务太繁杂了.他认为,上面的债务可以完全等价为 A 欠C20 元,B 既不欠别人,别人也不欠他.这样总债务规模就压缩到了 

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

(leetcode题解)Pascal&#39;s Triangle

Pascal's Triangle  Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5,Return [ [1], [1,1], [1,2,1], [1,3,3,1], [1,4,6,4,1] ] 题意实现一个杨辉三角. 这道题只要注意了边界条件应该很好实现出来,C++实现如下 vector<vector<int>> generate(int

2017ZZUACM省赛选拔试题部分题解----谨以纪念我这卡线滚粗的美好经历

写在前面: 其实心里有些小小的不爽又有点小小的舒畅,为啥捏?不爽当然是因为没被选拔上啦,舒畅捏则是因为没被选拔上反而让自己警醒,学长也提点很多很多."沉下去,然后一战成名"学长如是对我说,我很开心.其实这完全算不算是题解,只是我个人的一些小想法而已.而且到现在还有一题不会...让自己长点记性吧. 题目 A :聪明的田鼠 Time Limit: 1 Sec Memory Limit: 128 MB Description 田鼠MIUMIU来到了一片农田,农田可以看成是一个M*N个方格的矩

LeetCode-001题解

此题目摘自LeetCode001 Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2.

leetcode题解: Next Permutation

最近还一直在刷leetcode,当然,更多时候只是将题解写在自己的电脑上,没有分享出来.偶尔想起来的时候,就写出来. public class Solution { public void nextPermutation(int[] nums) { if(nums==null||nums.length<=1) return; nextPermutationHelp( nums,0,nums.length-1); } public void nextPermutationHelp(int []nu

HDU 5014 Number Sequence(2014 ACM/ICPC Asia Regional Xi&#39;an Online) 题解

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5014 Number Sequence Problem Description There is a special number sequence which has n+1 integers. For each number in sequence, we have two rules: ● ai ∈ [0,n] ● ai ≠ aj( i ≠ j ) For sequence a and sequ