链接: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.

输入例子:
abab
输出例子:
2
2 0 2
2 1 3

-->

示例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;
}

  

 

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

  1. 牛客网 暑期ACM多校训练营(第二场)A.run-动态规划 or 递推?

    牛客网暑期ACM多校训练营(第二场) 水博客. A.run 题意就是一个人一秒可以走1步或者跑K步,不能连续跑2秒,他从0开始移动,移动到[L,R]的某一点就可以结束.问一共有多少种移动的方式. 个人 ...

  2. 牛客网 暑期ACM多校训练营(第一场)A.Monotonic Matrix-矩阵转化为格子路径的非降路径计数,Lindström-Gessel-Viennot引理-组合数学

    牛客网暑期ACM多校训练营(第一场) A.Monotonic Matrix 这个题就是给你一个n*m的矩阵,往里面填{0,1,2}这三种数,要求是Ai,j⩽Ai+1,j,Ai,j⩽Ai,j+1 ,问你 ...

  3. 2018牛客网暑期ACM多校训练营(第二场)I- car ( 思维)

    2018牛客网暑期ACM多校训练营(第二场)I- car 链接:https://ac.nowcoder.com/acm/contest/140/I来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 ...

  4. 牛客网暑期ACM多校训练营(第一场) - J Different Integers(线段数组or莫队)

    链接:https://www.nowcoder.com/acm/contest/139/J来源:牛客网 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 524288K,其他语言1048 ...

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

    链接:https://www.nowcoder.com/acm/contest/147/A来源:牛客网 Niuniu has recently learned how to use Gaussian ...

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

    链接:https://www.nowcoder.com/acm/contest/147/D来源:牛客网 Niuniu likes traveling. Now he will travel on a ...

  7. 牛客网暑期ACM多校训练营(第二场)B discount

    链接:https://www.nowcoder.com/acm/contest/140/B来源:牛客网 题目描述 White Rabbit wants to buy some drinks from ...

  8. 2018牛客网暑期ACM多校训练营(第一场)D图同构,J

    链接:https://www.nowcoder.com/acm/contest/139/D来源:牛客网 同构图:假设G=(V,E)和G1=(V1,E1)是两个图,如果存在一个双射m:V→V1,使得对所 ...

  9. 牛客网暑期ACM多校训练营(第二场) I Car 思维

    链接:https://www.nowcoder.com/acm/contest/140/I来源:牛客网 White Cloud has a square of n*n from (1,1) to (n ...

  10. 牛客网暑期ACM多校训练营(第二场) D money 思维

    链接:https://www.nowcoder.com/acm/contest/140/D来源:牛客网 White Cloud has built n stores numbered from 1 t ...

随机推荐

  1. Loadrunner参数(摘)

    一.占有率分析 1. 平均事务响应时间 Average Transaction Response Time 优秀:<2s 良好:2-5s 及格:6-10s 不及格:>10s 2. 每秒点击 ...

  2. 2019前端面试系列——HTTP、浏览器面试题

    浏览器存储的方式有哪些 特性 cookie localStorage sessionStorage indexedDB 数据生命周期 一般由服务器生成,可以设置过期时间 除非被清理,否则一直存在 页面 ...

  3. hdu 6406 Taotao Picks Apples (线段树)

    Problem Description There is an apple tree in front of Taotao's house. When autumn comes, n apples o ...

  4. Java动态,安全追踪工具

    Java动态,安全追踪工具 在我们日常的开发中,总是难以避免的要解决线上的问题.如果线上的问题我们在本地调试的时候无论调试多少次发现明明本地调用了这个方法呀,怎么线上就是没调呢?还有就是出了问题的时候 ...

  5. gitee+hexo搭建个人博客

    通过gitee和hexo搭建个人博客 首先准备软件: git (提供命令git) git官网 notepad++(方便编辑)notepad++官网 nodejs(hexo依赖)nodejs官网 7z( ...

  6. cogs 264. 数列操作 单点修改 区间查询

    http://cogs.pro:8080/cogs/problem/problem.php?pid=pyNimmVeq 264. 数列操作 ★☆   输入文件:shulie.in   输出文件:shu ...

  7. android——SQLite数据库存储(操作)

    public class MyDatabaseHelper extends SQLiteOpenHelper { //把定义SQL建表语句成字符串常量 //图书的详细信息 //ID.作者.价格.页数. ...

  8. vue 辅助开发工具(利用node自动生成相关文件,自动注册路由)

    vue 辅助开发工具 前言 有没有因为新建view,component,store的繁琐操作而苦恼,需要新建文件件,新建vue文件,新建js文件,注册路由...等一系列无价值操作浪费时间,为了解决这个 ...

  9. Servlet生成验证码并进行账号密码和验证码的验证登陆!

    前言: 人不是生来就懂事的,在编程的世界也是一样,想想在大一的时候我还是那个连输出Hello World!都不会的小孩子是,现在我已经可以编出属于我自己的小程序了.编程其实并不可怕,可怕的是你不去编. ...

  10. html5新特性-header,nav,footer,aside,article,section等各元素的详解

    Html5新增了27个元素,废弃了16个元素,根据现有的标准规范,把HTML5的元素按优先级定义为结构性属性.级块性元素.行内语义性元素和交互性元素四大类. 下面是对各标签的详解,section.he ...