首页 > 代码库 > (HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)
(HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=5558
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 Nlowercase 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 Kand 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.
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 Kand 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
Source
2015ACM/ICPC亚洲区合肥站-重现赛(感谢中科大)
Recommend
wange2014 | We have carefully selected several similar problems for you: 5932 5931 5930 5929 5928
题意:输入一个只含有小写英文字母的字符串s[], 现在进行计算,对于当前位置i 在0~i-1 中找到j 使得后缀suffix[i] 和 suffix[j] 的公共前缀最长(设公共前缀长为k),输出长度和j,如果有多个j公共前缀长度一样,输出最小的j ,然后i=i+k 重复上述过程,直至i>=len;
思路:先用后缀数组模板计算出名次数组和后缀数组 及最长公共前缀height[]数组 ,然后对于i 求出i的排名,然后根据i的排名,向比i大和小的排名找,取一个最大值;
代码如下:
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>#include <bitset>using namespace std;const int N=1e5+5;char s[N];int wa[N],wb[N],wv[N],wss[N];int rankk[N],height[N],sa[N];int cmp(int *r,int a,int b,int l){ return r[a]==r[b]&&r[a+l]==r[b+l];}void da(char *r,int *sa,int n,int m){ int i,j,p,*x=wa,*y=wb,*t; for(i=0;i<m;i++) wss[i]=0; for(i=0;i<n;i++) wss[x[i]=r[i]]++; for(i=1;i<m;i++) wss[i]+=wss[i-1]; for(i=n-1;i>=0;i--) sa[--wss[x[i]]]=i; for(j=1,p=1;p<n;j*=2,m=p) { for(p=0,i=n-j;i<n;i++) y[p++]=i; for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j; for(i=0;i<n;i++) wv[i]=x[y[i]]; for(i=0;i<m;i++) wss[i]=0; for(i=0;i<n;i++) wss[wv[i]]++; for(i=1;i<m;i++) wss[i]+=wss[i-1]; for(i=n-1;i>=0;i--) sa[--wss[wv[i]]]=y[i]; for(t=x,x=y,y=t,p=1,x[sa[0]]=0,i=1;i<n;i++) x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++; } return ;}void calheight(char *r,int *sa,int n){ int i,j,k=0; for(i=1;i<=n;i++) rankk[sa[i]]=i; for(i=0;i<n;height[rankk[i++]]=k) for(k?k--:0,j=sa[rankk[i]-1];r[i+k]==r[j+k];k++); return ;}int main(){ int T,Case=1; cin>>T; while(T--) { scanf("%s",s); int len=strlen(s); da(s,sa,len+1,130); calheight(s,sa,len); printf("Case #%d:\n",Case++); int i=0; while(i<len) { int pos,k=0; int rk=rankk[i]; int d=height[rk]; for(int j=rk;j>=1&&height[j]!=0;j--) { d=min(d,height[j]); if(d<k) break; if(sa[j-1]<i&&((d>k)||(d==k&&sa[j-1]<pos))) { k=d; pos=sa[j-1]; } } if(rk<len){ d=height[rk+1]; for(int j=rk+1; j<=len&&height[j]!=0; j++) { d=min(d,height[j]); if(d<k) break; if(sa[j]<i&&((d>k)||(d==k&&sa[j]<pos))) { k=d; pos=sa[j]; } } } if(k) printf("%d %d\n",k,pos),i+=k; else printf("%d %d\n",-1,(int)s[i++]); } } return 0;}
(HDU 5558) 2015ACM/ICPC亚洲区合肥站---Alice's Classified Message(后缀数组)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。