HDU-6294 SA-IS后缀数组

SA-IS后缀数组

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 512000/512000 K (Java/Others)

Problem Description

小Q最近阅读了SA-IS算法在线性时间内构造后缀数组的相关论文,面对任何字符串题,都可以想出线性时间的算法。

小T在经历过二分图匹配事件后,再也不相信小Q所说的话。面对小Q,小T又给出了一道字符串题:

给定一个长度为n的小写字符串 S [ 1.. n ] S[1..n] S[1..n],设 s u f i suf_i sufi表示以 i i i为开始的后缀,即 S [ i . . n ] S[i..n] S[i..n]

∣ X ∣ |X| X为字符串X的长度,对于两个字符串 X X X Y Y Y,定义 X X X的字典序比 Y Y Y小,当且仅当存在非负整数 k ( k ≤ min ⁡ ( ∣ X ∣ , ∣ Y ∣ ) ) k(k\leq \min(|X|,|Y|)) k(kmin(X,Y))使得 X X X的前 k k k个字符与 Y Y Y的前 k k k个字符对应相同,并且要么满足 ∣ X ∣ = k |X| = k X=k ∣ Y ∣ > k |Y| > k Y>k,要么满足 k < min ⁡ ( ∣ X ∣ , ∣ Y ∣ ) k < \min(|X|,|Y|) k<min(X,Y) X X X的第 k + 1 k+1 k+1个字符比Y的第 k + 1 k+1 k+1个字符小。例如aa的字典序比aaa小,ab的字典序比ba小。

请对每个 i ( 1 ≤ i < n ) i(1\leq i<n) i(1i<n),判断 s u f i suf_i sufi s u f i + 1 suf_{i+1} sufi+1的字典序大小关系。

只会吹牛的小Q又不会做了,所以他再一次向你紧急求助。请写一个程序,判断相邻两个后缀的大小关系。

Input

第一行包含一个正整数T(1≤T≤10),表示测试数据的组数。

每组数据第一行包含一个正整数n(2≤n≤1000000),表示字符串S的长度。

第二行包含一个长度为n的小写字符串S。

Output

对于每组数据,输出一行n−1个字符,第i个字符表示sufi和sufi+1的大小关系,若sufi,显然不存在相等关系。

Sample Input

1
17
quailtyacmbestacm

Sample Output

<><<<<><<><<<><<

Tips

题意:
对于字符串 s [ 1.. n ] \text{s}[1..n] s[1..n],判断后 i i i 个字符组成的字串与后 i + 1 i+1 i+1 个字符组成的字串的字典序( 1 ⩽ i ⩽ n − 1 1\leqslant i\leqslant n-1 1in1 )。

题解:
f ( i ) f(i) f(i) 表示以i为开始的后缀。
首先判断 f ( n − 1 ) f(n-1) f(n1) f ( n ) f(n) f(n) 的大小关系。
对于 i i i ,如果 s [ i ] \text{s}[i] s[i] s [ i + 1 ] \text{s}[i+1] s[i+1] 有大小关系,则 f [ i ] f[i] f[i] f [ i + 1 ] f[i+1] f[i+1] 有一样的大小关系。
如果 s [ i ] = s [ i + 1 ] \text{s}[i]=\text{s}[i+1] s[i]=s[i+1] ,则 f [ i ] f[i] f[i] f [ i + 1 ] f[i+1] f[i+1] 的大小关系 ⇔ \Leftrightarrow f [ i + 1 ] f[i+1] f[i+1] f [ i + 2 ] f[i+2] f[i+2] 的大小关系。
(从后往前递推)。用栈保存结果之后输出。

Reference Code

#include
#include
#define maxn 1000005
char s[maxn];
using namespace std;
int main(){
	int ca;
	scanf("%d",&ca);
	while(ca--){
		int n;
		scanf("%d",&n);
		scanf("%s",s);
		stack<int>st;
		if(s[n-1]<s[n-2]||s[n-1]==s[n-2])st.push(1);
		else st.push(0);
		for(int i=n-2;i>=1;i--){
			if(s[i]<s[i-1])st.push(1);
			else if(s[i]>s[i-1])st.push(0);
			else st.push(st.top());
		}
		while(!st.empty()){
			if(st.top()==0)printf("<");
			else printf(">");
			st.pop();
		}
		printf("\n");
	}
	return 0;
}

你可能感兴趣的:(组队赛题解)