E Sort String

牛客网暑期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.

1≤ |S|≤ 10
6

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.
示例1

输入

复制
abab

输出

复制
2
2 0 2
2 1 3
示例2

输入

复制
deadbeef

输出

复制
8
1 0
1 1
1 2
1 3
1 4
1 5
1 6
1 7

解法一: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;
}

猜你喜欢

转载自www.cnblogs.com/longl/p/9377843.html