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 Haystack 全文检索与关键词高亮

    Django Haystack 简介 django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr.Elasticsearch.Whoosh.Xapian 等多 ...

  2. codevs 1283 等差子序列

    http://codevs.cn/problem/1283/ 题目描述 Description 给一个 1 到 N 的排列{Ai},询问是否存在 1<=p1<p2<p3<p4& ...

  3. windows系统下安装 node.js (node.js安装及环境配置)

    node.js简介 Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境. Node.js 使用了一个事件驱动.非阻塞式 I/O 的模型,使其轻量又高效. Node. ...

  4. 开始使用HTML5和CSS3验证表单

    使用HTML5和CSS3验证表单 客户端验证是网页客户端程序最常用的功能之一,我们之前使用了各种各样的js库来进行表单的验证.HTML5其实早已为我们提供了表单验证的功能.至于为啥没有流行起来估计是兼 ...

  5. JAVA_SE基础——32.this关键字调用本类的构造方法

    黑马程序员入学blog... 也算是学习笔记. 下面我们来看段代码: package day07; class Student{ int id; //身份证 String name; //名字 pub ...

  6. php的调试工具xdebug

    zend_extension = "D:/developsoftware/wamp/bin/php/php5.5.12/zend_ext/php_xdebug-2.2.5-5.5-vc11- ...

  7. es6学习笔记--Interator和Generator(以及for-of的用法)

    这几天学习了遍历器和生成器,看着资料学,有点雾里缭绕的感觉,让人忍不住放弃,还好多看了好几遍,怼着资料里的例子让自己学会了Interator和Generator.   Interator,中文简称:遍 ...

  8. 大数据学习总结(7)we should...

    大数据场景一.各种标签查询 查询要素:人.事.物.单位 查询范围:A范围.B范围.... 查询结果:pic.name.data from 1.痛点:对所有文本皆有实时查询需求2.难点:传统SQL使用W ...

  9. Docker学习实践 - Docker安装MySql数据库

    Docker安装MySQL数据库 1.Ubuntu安装MySQL安装 (1)安装编译源码需要的包 sudo apt-get install make cmake gcc g++ bison libnc ...

  10. SpringCloud的服务消费者 (一):(rest+ribbon)访问注册的微服务

    采用Ribbon或Feign方式访问注册到EurekaServer中的微服务.1.Ribbon实现了客户端负载均衡,Feign底层调用Ribbon2.注册在EurekaServer中的微服务api,不 ...