Alice's Classified Message

Time Limit: 16000/8000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 312    Accepted Submission(s): 122

Problem Description
Alice wants to send a classified message to Bob. She tries to encrypt the message with her original encryption method. The message is a string S, which consists of N lowercase letters.

S[a…b] means a substring of S ranging from S[a] to S[b] (0≤a≤b<N). If the first i letters have been encrypted, Alice will try to find a magic string P. Assuming P has K letters, P is the longest string which satisfies P=S[T...T+K−1] (0≤T<i,T+K≤N) and P=S[i…i+K−1](i+K≤N). In other words, P is a substring of S, of which starting address is within [0...i−1], and P is also a prefix of S[i...N−1]. If P exists, Alice will append integer K and T to ciphertext. If T is not unique, Alice would select the minimal one. And then i is incremented by K. If P does not exist, Alice will append -1 and the ASCII code of letter S[i] to ciphertext, and then increment i by 1.

Obviously the first letter cannot be encrypted. That is to say, P does not exist when i=0. So the first integer of ciphertext must be -1, and the second integer is the ASCII code of S[0].

When i=N, all letters are encrypted, and Alice gets the final ciphertext, which consists of many pairs of integers. Please help Alice to implement this method.

 
Input
The first line of input contains an integer T, which represents the number of test cases (T≤50). Each test case contains a line of string, which has no more than 100000 lowercase letters. It is guaranteed that the total length of the strings is not greater than 2×106.
 
Output
For each test case, output a single line consisting of “Case #X:” first. X is the test case number starting from 1. Output the ciphertext in the following lines. Each line contains two integers separated by a single space.
 
Sample Input
2
aaaaaa
aaaaabbbbbaaabbc
 
Sample Output
Case #1:
-1 97
5 0
Case #2:
-1 97
4 0
-1 98
4 5
5 2
-1 99
 /*
hdu5558 后缀数组 从[1,n]对于每个i,求suff[j](j < i)与suff[i]的最长公共前缀,
如果有多个,取最小的那个 我们可以通过后缀数组先求出,如果i-1和i,i和i+1都有公共前缀,
那么i-1和i+1也有公共前缀,所以可以先处理出每个i的左右界限。然后对于i左右扫描一下即可 然后枚举i,从pre[i]-nex[i]找到合适的结果即可 hhh-2016-03-10 18:17:04
*/
#include <algorithm>
#include <cmath>
#include <queue>
#include <iostream>
#include <cstring>
#include <map>
#include <cstdio>
#include <vector>
#include <functional>
#define lson (i<<1)
#define rson ((i<<1)|1)
using namespace std;
typedef long long ll;
const int maxn = ; int t1[maxn],t2[maxn],c[maxn];
bool cmp(int *r,int a,int b,int l)
{
return r[a]==r[b] &&r[l+a] == r[l+b];
} void get_sa(int str[],int sa[],int Rank[],int height[],int n,int m)
{
n++;
int p,*x=t1,*y=t2;
for(int i = ; i < m; i++) c[i] = ;
for(int i = ; i < n; i++) c[x[i] = str[i]]++;
for(int i = ; i < m; i++) c[i] += c[i-];
for(int i = n-; i>=; i--) sa[--c[x[i]]] = i;
for(int j = ; j <= n; j <<= )
{
p = ;
for(int i = n-j; i < n; i++) y[p++] = i;
for(int i = ; i < n; i++) if(sa[i] >= j) y[p++] = sa[i]-j;
for(int i = ; i < m; i++) c[i] = ;
for(int i = ; i < n; i++) c[x[y[i]]]++ ;
for(int i = ; i < m; i++) c[i] += c[i-];
for(int i = n-; i >= ; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y);
p = ;
x[sa[]] = ;
for(int i = ; i < n; i++)
x[sa[i]] = cmp(y,sa[i-],sa[i],j)? p-:p++;
if(p >= n) break;
m = p;
}
int k = ;
n--;
for(int i = ; i <= n; i++)
Rank[sa[i]] = i;
for(int i = ; i < n; i++)
{
if(k) k--;
int j = sa[Rank[i]-];
while(str[i+k] == str[j+k]) k++;
height[Rank[i]] = k;
}
} int pre[maxn],nex[maxn];
int Rank[maxn],height[maxn];
int sa[maxn],str[maxn];
char a[maxn];
int len; int main()
{
int T,cas = ;
scanf("%d",&T);
while(T--)
{
scanf("%s",a);
int len = ;
for(int i =;a[i] != '\0'; i++)
{
str[len++] = a[i]-'a'+;
}
str[len] = ;
get_sa(str,sa,Rank,height,len,); for(int i = ; i <= len; i++)
{
if(height[i] == )
pre[i] = i;
else
pre[i] = pre[i-];
} for(int i = len; i >= ; i--)
{
if(height[i+] == || i == len) nex[i] = i;
else nex[i] = nex[i+];
} int i = ;
printf("Case #%d:\n",cas++);
while(i < len)
{
int now = Rank[i]; //i的排名
int k = ,t = i;
int mi = height[now];
for(int j = now-; j >= pre[now]; j--)
{
mi = min(mi,height[j+]);
if(mi < k)
break;
if(sa[j] < i)
{
if(mi > k || (mi==k && sa[j] < t))
{
k = mi;
t = sa[j];
}
}
}
if(now+ <= nex[now]) mi = height[now+];
for(int j = now+; j <= nex[now]; j++)
{
mi = min(mi,height[j]);
if(mi < k)
break;
if(sa[j] < i)
{
if(mi > k || (mi==k && sa[j] < t))
{
t = sa[j];
k = mi;
}
}
} if(k == ) printf("-1 %d\n",a[i]);
else printf("%d %d\n",k,t);
if(k) i+=k;
else i++;
}
}
return ;
}
												

hdu5558 后缀数组的更多相关文章

  1. HDU5558 Alice's Classified Message(合肥区域赛 后缀数组)

    当初合肥区域赛的题(现场赛改了数据范围就暴力过了),可惜当初后缀数组算法的名字都没听过,现在重做下. i从1到n - 1,每次枚举rank[i]附近的排名,并记录当起点小于i时的LCP(rank[i] ...

  2. 后缀数组的倍增算法(Prefix Doubling)

    后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ...

  3. BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]

    4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ...

  4. BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]

    1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1383  Solved: 582[Submit][St ...

  5. POJ3693 Maximum repetition substring [后缀数组 ST表]

    Maximum repetition substring Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9458   Acc ...

  6. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  7. 后缀数组(suffix array)详解

    写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ...

  8. 【UOJ #35】后缀排序 后缀数组模板

    http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ...

  9. 【BZOJ-2119】股市的预测 后缀数组

    2119: 股市的预测 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 334  Solved: 154[Submit][Status][Discuss ...

随机推荐

  1. django搭建web (五) views.py

    http请求: HttpRequest http响应: HttpResponse 所在位置:django.http isinstance(request,HttpResponse) True-> ...

  2. Linux下Java通用安装方法

    1.到oracle官网下下载对应jdk包,一般为%x64%.tar.gz格式. 2.建立目录: $ mkdir /usr/local/java 3.将压缩包解压至/usr/local/java 4.修 ...

  3. 200行Python代码实现2048

    200行Python代码实现2048 一.实验说明 1. 环境登录 无需密码自动登录,系统用户名shiyanlou 2. 环境介绍 本实验环境采用带桌面的Ubuntu Linux环境,实验中会用到桌面 ...

  4. 【iOS】Swift LAZY 修饰符和 LAZY 方法

    延时加载或者说延时初始化是很常用的优化方法,在构建和生成新的对象的时候,内存分配会在运行时耗费不少时间,如果有一些对象的属性和内容非常复杂的话,这个时间更是不可忽略.另外,有些情况下我们并不会立即用到 ...

  5. 【iOS】OC-时间转化的时区问题

    -(void)testTime{ NSDate *now = [NSDate date];//根据当前系统的时区产生当前的时间,绝对时间,所以同为中午12点,不同的时区,这个时间是不同的. NSDat ...

  6. 集合Collection总览

    前言 声明,本文使用的是JDK1.8 从今天开始正式去学习Java基础中最重要的东西--->集合 无论在开发中,在面试中这个知识点都是非常非常重要的,因此,我在此花费的时间也是很多,得参阅挺多的 ...

  7. Python入门之迭代器/生成器/yield的表达方式/面向过程编程

    本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...

  8. FTP文件上传到HDFS上

    在做测试数据时,往往会有ftp数据上传到hdfs的需求,一般需要手动操作,这样做太费事,于是有了下边代码实现的方式: ftp数据上传到hdfs函数: import java.io.InputStrea ...

  9. python自带的web服务器

    python自带的web服务器 python自带的包可以建立简单的web服务器 BaseHTTPServer 提供基本的web服务和处理类 SimpleHTTPServer 包含执行get请求的Sim ...

  10. Spring(5)——Spring 和数据库编程

    传统 JDBC 回顾 JDBC 我们一定不陌生,刚开始学习的时候,我们写过很多很多重复的模板代码: public Student getOne(int id) { String sql = " ...