E、Sort String(字符串hash)

链接:https://ac.nowcoder.com/acm/problem/17244
来源:牛客网

题目描述

Eddy likes to play with string which is a sequence of characters. One day, Eddy has played with a string S for a long time and wonders how could make it more enjoyable. Eddy comes up with following procedure:

1. For each i in [0,|S|-1], let Si be the substring of S starting from i-th character to the end followed by the substring of first i characters of S. Index of string starts from 0.
2. Group up all the Si. Si and Sj will be the same group if and only if Si=Sj.
3. For each group, let Lj be the list of index i in non-decreasing order of Si in this group.
4. Sort all the Lj by lexicographical order.

Eddy can't find any efficient way to compute the final result. As one of his best friend, you come to help him compute the answer!
 

题目大意:

就是给你一个字符串,长度为len。然后这个字符串可以分解成len个长度为len的字符串,每一次分割是从第i个位置到最后,然后后面在接上0~i-1位置的字符串,然后相同的字符串归类,
每一类的字符串中编号按照从小到大分类。

具体思路:

字符串hash

优化过程:一开始每一次对字符串进行标记,然后再去进行计算。这样会占用大量的内存(所以超内存了)。

然后我们可以采用字符串hash的形式,把每一个字符串转换成一个整数,在hash的时候,我们可以将ind函数的初始化和对字符串hash放进同一个字符串里面,这样就会省去大量的内存(然后超时了)。

再去分析一波,我一开始用的是set,也就是会自动排序,然后发现不需要排序这个过程,因为放入的过程就是一个有序的过程,然后把set改成vector就好了。

然后发现还是超时,我们再就是输出的那个for循环进行优化了,一开始用了auto关键词,我们可以把它改成for循环,并且对于终止条件用一个int型的变量进行求解,这样就不用每一次都去测量长度了。

还是超时,然后我们发现输出的那个for循环,会跑到1e6,然后我们可以在计算的过程中,直接存储第一个出现的,然后输出的时候直接按照存储的第一个出现的字符就好了。

AC代码:

 1 #pragma comment(linker,"/STACK:1024000000,1024000000")
 2 #include<bits/stdc++.h>
 3 using namespace std;
 4 # define ll long long
 5 # define ull unsigned long long
 6 # define inf 0x3f3f3f3f3f
 7 # define base 131
 8 const int maxn = 2e6+100;
 9 char str[maxn];
10 ull ind[maxn];
11 //void init()
12 //{
13 //    ind[0]=1;
14 //    for(int i=1; i<maxn; i++)
15 //    {
16 //        ind[i]=ind[i-1]*base;
17 //    }
18 //}
19 ull Hash[maxn];
20 void cal(int len)
21 {
22     ind[0]=1;
23     Hash[0]=1;
24     for(int i=1; i<=len; i++)
25     {
26         Hash[i]=Hash[i-1]*base + (ull)str[i];
27           ind[i]=ind[i-1]*base;
28     }
29 }
30 ull getsub(int l,int r)
31 {
32     return Hash[r]-Hash[l-1]*ind[r-l+1];
33 }
34 unordered_map<ull,int>vis;
35 vector<int>sto[maxn];
36 int main()
37 {
38    // init();
39     scanf("%s",str+1);
40     int len=strlen(str+1);
41     for(int i=len+1; i<=len+len; i++)
42     {
43         str[i]=str[i-len];
44     }
45     int num=0;
46     cal(len+len);
47     for(int i=1; i<=len; i++)
48     {
49         ull tmp=getsub(i,i+len-1);
50         if(!vis[tmp]){
51             vis[tmp]=++num;
52         }
53         sto[vis[tmp]].push_back(i-1);
54     }
55     printf("%d
",num);
56     for(int i=1; i<=num; i++)
57     {int len=sto[i].size();
58         printf("%d",len);
59         for(int j=0;j<len;j++)
60         {
61             printf(" %d",sto[i][j]);
62         }
63         printf("
");
64     }
65     return 0;
66 }
原文地址:https://www.cnblogs.com/letlifestop/p/10919805.html