牛客网暑期ACM多校训练营(第三场) E Sort String
题目:
链接:https://www.nowcoder.com/acm/contest/141/E
来源:牛客网时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld
题目描述
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 S i 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 S i. S i and S j will be the same group if and only if S i=S j.
3. For each group, let L j be the list of index i in non-decreasing order of S i in this group.
4. Sort all the L j 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!输入描述:
Input contains only one line consisting of a string S.6
1≤ |S|≤ 10
S only contains lowercase English letters(i.e.).输出描述:
First, output one line containing an integer K indicating the number of lists.
For each following K lines, output each list in lexicographical order.
For each list, output its length followed by the indexes in it separated by a single space.
解法一:hash
思路:
复制一遍字符串,然后预处理hash表。之后for每个起始位置,可以在O(1)的时间获取子串的hash值,然后扔进map分类即可。对于这种写法字典序不需要特殊处理。
注意:
1.要注意mod的选取,不然会tle,这里选用了ull(自动%2^64)
2.要用unordered_map,不然会tle
3.要用快速输出,不然可能tle
代码:
#include<cstdio> #include<iostream> #include<unordered_map> #include<cstring> #include<vector> using namespace std; typedef unsigned long long ull; const int maxn = 2e6+10; ///快速输出模板 int buf[40]; template<class M> inline void write(M x) { int p=0; if(x<0){ putchar('-'); x=-x; } do{ buf[p++]=x%10; x/=10; }while(x); for(int i=p-1;i>=0;i--) putchar(buf[i]+'0'); // putchar('\n'); } struct HashTable { ull base; ull Hash[maxn],tmp[maxn]; void setBase(ull _base) { base = _base; } void getHashTable(char *s, int len) { tmp[0]=1; for(int i=1; i<=len; i++) tmp[i]=tmp[i-1]*base; Hash[0]=0; for(int i=1; i<=len; i++) Hash[i]=Hash[i-1]*base+(s[i]-'a'); } ull getHash(int l, int r) { return Hash[r]-Hash[l-1]*tmp[r-l+1]; } } hashTable; char s[maxn]; unordered_map<ull,int> mp; vector<int> res[maxn/2]; int main() { scanf("%s",s+1); int len = strlen(s+1); ///翻倍一次 for(int i=1; i<=len; i++) s[i+len]=s[i]; ///预处理出哈希表 hashTable.setBase(13); hashTable.getHashTable(s,2*len); ///计算答案 int tot=0; for(int i=1; i<=len; i++) { ull lr_hash = hashTable.getHash(i,i+len-1); // printf("%llu\n",lr_hash); if(mp.find(lr_hash)==mp.end()) { mp[lr_hash]=++tot; } res[mp[lr_hash]].push_back(i-1);///下标从0开始 } ///输出答案 write(tot); puts(""); for(int i=1; i<=tot; i++) { write(res[i].size()); for(int j=0; j<res[i].size(); j++) { printf(" "); write(res[i][j]); } puts(""); } return 0; }