SA-IS后缀数组
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 512000/512000 K (Java/Others)Total Submission(s): 226 Accepted Submission(s): 75
Problem Description
小Q最近阅读了SA-IS算法在线性时间内构造后缀数组的相关论文,面对任何字符串题,都可以想出线性时间的算法。
小T在经历过二分图匹配事件后,再也不相信小Q所说的话。面对小Q,小T又给出了一道字符串题:
给定一个长度为 n的小写字符串 S[1..n],设 sufi表示以 i 为开始的后缀,即 S[i..n]。
记 |X|为字符串 X的长度,对于两个字符串 X和 Y,定义 X的字典序比 Y小,当且仅当存在非负整数 k(k≤min(|X|,|Y|))使得 X的前 k个字符与 Y的前 k个字符对应相同,并且要么满足 |X|=k且 |Y|>k,要么满足 k<min(|X|,|Y|)且 X的第 k+1个字符比 Y的第 k+1个字符小。例如aa的字典序比aaa小,ab的字典序比ba小。
请对每个 i(1≤i<n),判断 sufi和 sufi+1的字典序大小关系。
只会吹牛的小Q又不会做了,所以他再一次向你紧急求助。请写一个程序,判断相邻两个后缀的大小关系。
小T在经历过二分图匹配事件后,再也不相信小Q所说的话。面对小Q,小T又给出了一道字符串题:
给定一个长度为 n的小写字符串 S[1..n],设 sufi表示以 i 为开始的后缀,即 S[i..n]。
记 |X|为字符串 X的长度,对于两个字符串 X和 Y,定义 X的字典序比 Y小,当且仅当存在非负整数 k(k≤min(|X|,|Y|))使得 X的前 k个字符与 Y的前 k个字符对应相同,并且要么满足 |X|=k且 |Y|>k,要么满足 k<min(|X|,|Y|)且 X的第 k+1个字符比 Y的第 k+1个字符小。例如aa的字典序比aaa小,ab的字典序比ba小。
请对每个 i(1≤i<n),判断 sufi和 sufi+1的字典序大小关系。
只会吹牛的小Q又不会做了,所以他再一次向你紧急求助。请写一个程序,判断相邻两个后缀的大小关系。
Input
第一行包含一个正整数
T(1≤T≤10),表示测试数据的组数。
每组数据第一行包含一个正整数 n(2≤n≤1000000),表示字符串 S的长度。
第二行包含一个长度为 n的小写字符串 S。
每组数据第一行包含一个正整数 n(2≤n≤1000000),表示字符串 S的长度。
第二行包含一个长度为 n的小写字符串 S。
Output
对于每组数据,输出一行
n−1个字符,第
i个字符表示
sufi和
sufi+1的大小关系,若
sufi<sufi+1,输出
<,否则输出
>,显然不存在相等关系。
Sample Input
1 17 quailtyacmbestacm
Sample Output
<><<<<><<><<<><<
Source
解题思路:贪心从前往后扫,可以直接记录答案。关键在于处理相等的情况。实际上,相等的情况可以从后往前推出。
#include<bits/stdc++.h> using namespace std; typedef long long int ll; char str[1000005]; char ans[1000005]; int main(){ int T; scanf("%d",&T); for(int qqq=1;qqq<=T;qqq++){ memset(ans,0,sizeof(ans)); int N; scanf("%d",&N); scanf("%s",str); for(int i=0;i<N;i++){ if(str[i]<str[i+1]){ ans[i]='<'; } else{ if(str[i]>str[i+1]){ ans[i]='>'; } } } char cur=ans[N-1]; for(int i=N-2;i>=0;i--){ if(ans[i]==0) ans[i]=cur; else{ cur=ans[i]; } } ans[N-1]='\0'; printf("%s\n",ans); } return 0; }