Alice’s Classified Message(传送门)
Time Limit : 16000/8000ms (Java/Other) Memory Limit : 131072/131072K (Java/Other)
Total Submission(s) : 5 Accepted Submission(s) : 2
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
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
Obviously the first letter cannot be encrypted. That is to say,
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 (
Output
For each test case, output a single line consisting of “[b]Case #X:[/b]” 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
Source
2015ACM/ICPC亚洲区合肥站-重现赛(感谢中科大)
题意
给定一个字符串
每次对于下标
如果存在则输出匹配的最长的子串的长度和它开始匹配的位置
如果不存在输出-1,和当前
解题思路
可以将题目问题转换为求解位置
i
开始的后缀和以位置
代码
/*除去冗长的头文件*/
const double PI = 3.1415926535898;
const double eps = 1e-10;
const int MAXM = 1e5 + 5;
const int MAXN = 2e6 + 5;
const int INF = 0x3f3f3f3f;
/*len表示当前匹配的最长子串的长度,pos表示位置,hzp表示后缀转移*/
const int CHAR = 26;
struct SAM_Node {
int len, pos;
int id;
SAM_Node *hzp, *next[CHAR];
SAM_Node() {}
SAM_Node(int _len) {
len = _len;
hzp = 0;
mem(next, 0);
}
void Init(){
mem(next, 0);
}
} SAM_node[MAXN << 1], *SAM_root, *SAM_last;
int SAM_sz;
SAM_Node *newSAM_Node(int len) {
SAM_node[SAM_sz].len = len;
SAM_node[SAM_sz].id = SAM_sz;
SAM_node[SAM_sz].Init();
return &SAM_node[SAM_sz ++];
}
SAM_Node *newSAM_Node(SAM_Node *p) {
SAM_node[SAM_sz] = *p;
SAM_node[SAM_sz].id = SAM_sz;
return &SAM_node[SAM_sz ++];
}
void SAM_Init() {
SAM_sz = 0;
SAM_root = SAM_last = newSAM_Node(0);
SAM_node[0].pos = 0;
}
void SAM_add(int c, int pos) {
SAM_Node *p = SAM_last, *np = newSAM_Node(p -> len + 1);
np -> pos = pos;
SAM_last = np;
for(; p && !p -> next[c]; p = p -> hzp) {
p -> next[c] = np;
}
if(!p) {
np -> hzp = SAM_root;
} else {
SAM_Node *q = p -> next[c];
if(p -> len + 1 == q -> len) {
np -> hzp = q;
} else {
SAM_Node *nq = newSAM_Node(q);
nq -> len = p -> len + 1;
q -> hzp = nq;
np -> hzp = nq;
for(; p && p -> next[c] == q; p = p -> hzp) {
p -> next[c] = nq;
}
}
}
}
int T;
char S[MAXN];
int main() {
#ifndef ONLINE_JUDGE
//FIN;
//FOUT;
#endif
IO_Init();
scanf("%d", &T);
int cas = 1;
while(T --) {
scanf("%s", S);
SAM_Init();
printf("Case #%d:\n", cas ++);
int now = 0, n = strlen(S);
while(now < n) {
int length = 0;
SAM_Node * cur = SAM_root;
while(now < n && cur -> next[S[now] - 'a'] != 0) {
cur = cur -> next[S[now] - 'a'];
length ++;
SAM_add(S[now] - 'a', now);
now ++;
}
if(length == 0) {
SAM_add(S[now] - 'a', now);
printf("-1 %d\n", S[now ++]);
} else {
printf("%d %d\n", length, cur -> pos - length + 1);
}
}
}
return 0;
}