Gildong最近学会了如何在O(nlogn)时间内找到长度为n的序列的最长递增子序列(LIS)。他想测试一下自己是否能正确实现,但他在网上找不到任何能做到的裁判(尽管实际上有很多)。因此,他要为你做一个关于对1到n之间的n个不同的整数进行排列组合的测验,用你的输出来测试他的代码。
测验的内容如下。
Gildong提供了一个长度为n-1的字符串,仅由字符'<'和'>'组成。第i个(1-索引)字符是序列中第i个元素和第i+1个元素之间的比较结果。如果字符串的第i个字符是'<',那么序列的第i个元素就小于第i+1个元素。如果字符串的第i个字符是'>',那么序列的第i个元素就大于第i+1个元素。
他想让你找到两个可能的序列(不一定是不同的),由1到n之间的n个不同的整数组成,每个都满足比较结果,其中第一个序列的LIS的长度是最小可能,第二个序列的LIS的长度是最大可能。
输入
每个测试包含一个或多个测试案例。第一行包含测试用例的数量t(1≤t≤104)。
每个测试用例正好包含一行,由一个整数和一个仅由字符'<'和'>'组成的字符串组成。整数是n (2≤n≤2⋅105),你需要找到的排列组合的长度。字符串是描述中解释的比较结果。字符串的长度为n-1。
保证所有测试案例中所有n的总和不超过2⋅105。
输出
对于每个测试案例,打印两行,每行有n个整数。第一行是具有最小长度的LIS的序列,第二行是具有最大长度的LIS的序列。如果有多个答案,打印其中任何一个。每个序列应该包含1到n之间的所有整数,包括在内,并且应该满足比较的结果。
可以证明,至少有一个答案总是存在的。
例子
输入复制
3
3 <<
7 >><>><
5 >>><
输出拷贝
1 2 3
1 2 3
5 4 3 7 2 1 6
4 3 1 7 5 2 6
4 3 2 1 5
5 4 2 1 3
注意
在第一种情况下,1 2 3是唯一可能的答案。
在第二种情况下,最短的LIS长度是2,最长的LIS长度是3。在最大LIS序列的例子中,4 '3' 1 7 '5' 2 '6' 可以是可能的LIS之一。
题意:给你一个数字n,与一串长为n-1的字符串,只包括<与>,构建一个最短上升子序列,与最长上升子序列,通过n的排列组合
题解:构建最短上升子序列时,我们应该让尽量大的数放在前面,遇到<时改变,
构建最长上升子序列时,根据(dirworth定理)
最长上升子序列的长度为,非上升子序列的个数(在这题里就是下降子序列的个数)
应让尽量小的数在前,遇到>时改变
#include<iostream>
#include<string>
using namespace std;
int ans1[200050],ans2[200050];
int main()
{
int t;
cin >> t;
while(t--)
{
int n;
string s;
cin >>n >>s;
int m = n;
for(int i = 0;i < n;i++)
{
int len = 1;
while(i < n&&s[i] == '<')
{
len++;
i++;
}
for(int j = i;j > i-len;j--)
ans1[j] = m--;
}
m = 1;
for(int i = 0; i < n;i++)
{
int len = 1;
while(i < n&s[i]=='>')
{
len ++;
i++;
}
for(int j = i;j > i-len;j --)
ans2[j] = m++;
}
for(int i =0; i <n;i++)
cout<<ans1[i] <<" ";
printf("\n");
for(int i =0; i <n;i++)
cout<<ans2[i] <<" ";
printf("\n");
}
}