链接:https://www.nowcoder.com/acm/contest/141/E
来源:牛客网

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!

输入描述:

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

题意:根据原字符串构造新串,对于原字符串从0~|S|-1,i从0开始,从i到最后的子串放到从0到i-1子串的前面。对于这些新构造的子串,从0开始编号,将相同的新字符串们归为一组,输出一共有多少组,每组有多少个新字符串,以及新字符串的编号。分析:按照题目的意思一步步来  (1)对于第一种条件,我们需要将字符串分成n个子串,从i=0开始,将i后面的子串放到前面去,这样生成n个子串  (2)然后对于每个子串我们需要将相同的子串放在一个集合内,这样产生m个集合  (3)每个集合内的子串按照他在原来的主串中的切割位置按递增排序  (4)将集合按照其内的切割位置按照字典序排序然后我们来分析做法首先是暴力做法:  (1)直接记录每个子串,用string自带的substr函数(看源码这个函数的时间复杂度为O(n))  (2)我们用map记录下每个字符串出现的次数,则map里的每个字符串就有了自己对应的集合  (3)在用map记录时,我们可以用个vector数组记录下每个字符串切割的位置  (4)将vector存在一个结构体里面,然后将vector里的值转成string,通过比较string排序如果这样暴力做的话很明显会时间超限,内存超限(当n为10^6时,map和结构体内的每个string存了10^6长的字符串会超内存限制)我们肯定不能通过存字符串来进行操作,于是我们想到了用哈希处理字符串,然后存下每个字符串的哈希值,注意此时要保证的是每个字符串的哈希值独一无二(如果你有时间可以计算下10^6个字符转化成整数最大的值),我是通过几次wa得出用哈希取余的值要大于10^12用哈希处理字符串后我们可以得到一个哈希的数组,然后我们可以用过一次sort排序将哈希值(字符串的值)按从小到大排序,这样不仅相同的字符串会在一起而且可以得到一个有序的哈希序列接下来我们直接遍历哈希数组,将相同的值加入同一个集合内(我用了一个数组存集合),判断的时候因为相同的在一起,所以如果后面等于前面i可以一直加,用一个数组保存i加了多少次,那么这个数组的每个值就对应了每个集合的长度,这样方便了我们以后遍历集合中间还有些细节操作看代码把
#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
#define debug(a) cout << #a << " " << a << endl
using namespace std;
typedef long long ll;
const ll maxn = 1e6+10;
const ll mod = 1000000000000023;
char s[maxn];
ll n, k, ans;
ll a[maxn], len[maxn], vis[maxn];
struct node {ll sum, pos;
}h[maxn];
bool cmp( node p, node q ) {if( p.sum == q.sum ) {return p.pos < q.pos;}return p.sum < q.sum;
}
int main() {ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);scanf("%s",s);for( ll i = 0; i < maxn; i ++ ) {a[i] = len[i] = vis[i] = h[i].sum = h[i].pos = 0;}ll n = strlen(s);ll t = 1;for( ll i = 0; i < n; i ++ ) {h[0].sum = ( h[0].sum*37 + s[i]-'?' ) % mod;if( i ) {t = 37*t%mod;}}for( ll i = 1; i < n; i ++ ) {h[i].sum = ( (h[i-1].sum-t*(s[i-1]-'?')%mod+mod)*37+s[i-1]-'?' )%mod;h[i].pos = i;}sort( h, h+n, cmp );k = 0;for( ll i = 0; i < n; i ++ ) {t = i;while( t+1<n && h[t+1].sum==h[t].sum ) {t ++;}a[++k] = i;len[k] = t-i+1;vis[h[i].pos] = k;i = t;}ans = 0;for( ll i = 0; i < n; i ++ ) {if( vis[i] ) {ans ++;}};printf("%lld\n",ans);for( ll i = 0; i < n; i ++ ) {if( vis[i] ) {printf("%lld",len[vis[i]]);for( ll j = a[vis[i]]; j < a[vis[i]]+len[vis[i]]; j ++ ) {printf(" %lld",h[j].pos);}printf("\n");}}return 0;
}

  

 

转载于:https://www.cnblogs.com/l609929321/p/9376715.html

牛客网暑期ACM多校训练营(第三场) E Sort String 哈希处理字符串(模板)相关推荐

  1. 牛客网暑期ACM多校训练营(第三场): E. Sort String(KMP)

    链接:https://www.nowcoder.com/acm/contest/141/E 来源:牛客网 题目描述 Eddy likes to play with string which is a ...

  2. 牛客网暑期ACM多校训练营(第三场): A. Ternary String(欧拉降幂+递推)

    题目描述 A ternary string is a sequence of digits, where each digit is either 0, 1, or 2. Chiaki has a t ...

  3. 牛客网暑期ACM多校训练营(第三场): C. Shuffle Cards(splay)

    链接:https://www.nowcoder.com/acm/contest/141/C 来源:牛客网 题目描述 Eddy likes to play cards game since there ...

  4. 牛客网暑期ACM多校训练营(第三场): C. Chiaki Sequence Reloaded(数位DP)

    题目描述 Chiaki is interested in an infinite sequence a1, a2, a3, ..., which defined as follows: Chiaki ...

  5. 牛客网暑期ACM多校训练营(第九场)

    牛客网暑期ACM多校训练营(第九场) A. Circulant Matrix 做法:看到下标 \(xor\) 这种情况就想 \(FWT\),可是半天没思路,于是放弃了..其实这个 \(n\) 疯狂暗示 ...

  6. 牛客网暑期ACM多校训练营(第一场)

    牛客网暑期ACM多校训练营(第一场) A. Monotonic Matrix 考虑0和1的分界线,1和2的分界线,发现问题可以转化为两条不互相穿过的路径的方案数(可重叠),题解的做法就是把一条路径斜着 ...

  7. 牛客网暑期ACM多校训练营(第二场): H. travel(树形线头DP)

    链接:https://ac.nowcoder.com/acm/contest/140/H 来源:牛客网 题目描述 White Cloud has a tree with n nodes.The roo ...

  8. 牛客网暑期ACM多校训练营(第二场)A .run

    链接:https://www.nowcoder.com/acm/contest/140/A 来源:牛客网 题目描述 White Cloud is exercising in the playgroun ...

  9. 牛客网暑期ACM多校训练营(第一场) J (莫队算法)

    题目链接:https://www.nowcoder.com/acm/contest/139/J 题目大意:给一个序列,进行q次查询,问1~l和r~n中有多少个不同的数字 题目思路:之前只是听说过莫队算 ...

  10. 牛客网暑期ACM多校训练营(第二场)J farm (二维树状数组)

    题目链接: https://www.nowcoder.com/acm/contest/140/J 思路: 都写在代码注释里了,非常好懂.. for_each函数可以去看一下,遍历起vector数组比较 ...

最新文章

  1. python web游戏实例_python实现的简单文本类游戏实例
  2. eplan怎么插入表格_EPLAN电气图实例控制柜(控制面板)
  3. 当RabbitMQ使用Publish发布消息出现数据格式问题的解决方法
  4. 单实例模式(singleton)
  5. 2008年毕业生第一份工作月薪工资大曝光
  6. 打印出重复的姓名和重复的次数,并按重复次数排序:
  7. MSDN中Enumerating All Processes枚举所有进程事例编译错误解析办法
  8. 系统带你学习 WebAPIs 第二讲
  9. 得到classpath和当前类的绝对路径的一些方法
  10. flash加xml图片叠加焦点图,左右箭头翻页
  11. java opencv 平移_Java中使用opencv
  12. pyCharm最新2017激活
  13. 边缘AI计算新时代,人工神经网络秒变脉冲神经网络
  14. 18. javacript高级程序设计-JavaScript与XML
  15. Bad version number in .class file问题解决
  16. 学习Javascript闭包(Closure)(转载+理解心得)
  17. ssh工作流程及原理
  18. i7-10750H和i7-8750H 对比哪个好
  19. thinkphp框架复习知识点
  20. Matlab 生成方波信号

热门文章

  1. AC日记——[ZJOI2009]狼和羊的故事 bzoj 1412
  2. 4月8日--关于Date的练习题--自定义获取当前时间
  3. java实现.net中的枚举
  4. mybatis审查要点
  5. 转:PHP中实现非阻塞模式
  6. linux的文件权限分析
  7. file结构体中private_data指针的疑惑
  8. 年轻人不讲武德不仅白piao接口测试知识还白piao接口测试工具会员
  9. Spring MVC拦截器(Interceptor)的配置及使用
  10. Selenium select-下拉列表处理