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. Java的HelloWorld程序

    Java的HelloWorld程序 1.新建文本文档,编写HelloWorld程序,最后保存时记得保存成.java格式 2.在D盘新建一个HelloJava文件夹用于保存java程序 3.使用WIN+ ...

  2. 201621123031 《Java程序设计》第6周学习总结

    作业06-接口.内部类 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多 ...

  3. 【iOS】swift-通过JS获取webView的高度

     let webHeightStr = webView.stringByEvaluatingJavaScriptFromString("document.body.scrollHeight& ...

  4. 【Fungus入门】10分钟快速构建Unity中的万能对话系统 / 叙事系统 / 剧情系统

    我真的很久没有写过一个完整的攻略了(笑),咸鱼了很久之后还是想来写一个好玩的.这次主要是梳理一下Unity的小众插件Fungus的核心功能,并且快速掌握其使用方法. 官方文档:http://fungu ...

  5. Ubuntu命令行连接WPA/WPA2无线网线

    一,连接无加密无线网络zhang:sudo ip link set wlan0 up sudo iw dev wlan0 connect zhangsudo dhclient wlan0 二,连接WP ...

  6. jenkins 简单实现php集成上线部署

    基于公司git版本控制,搭建jenkins实现php集成部署(没有用gitlab,测试服配置较低,gitlab卡的不要不要的了-) 一.安装jenkins相关依赖 wget -O /etc/yum.r ...

  7. Mego开发文档 - 索引

    Mego 开发文档 Mego 快速概述 主要特性 获取Mego 使用流程 模型 查询 保存数据 入门 Mego 快速开始 创建项目 安装Nuget包 创建连接字符串 创建模型及数据上下文(添加引用) ...

  8. 新概念英语(1-127)A famous actoress(女演员)

    A:Can you recognize that woman, Liz ?B:I think I can, Kate. It must be Karen Marsh, the actoress.A:I ...

  9. eclipse+Maven插件报错:-Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable and mvn script match.

    问题描述: eclipse indigo+maven3.3.3+jdk1.70 maven插件执行报错:-Dmaven.multiModuleProjectDirectory system prope ...

  10. EasyUI combobox下拉多选框的实现

    combobox实现下拉列表多选, 效果如下