Codeforces - Increasing Subsequence(easy & hard version)

    xiaoxiao2023-10-16  32

    一、Increasing Subsequence (easy version)

    The only difference between problems C1 and C2 is that all values in input of problem C1 are distinct (this condition may be false for problem C2).

    You are given a sequence ?a consisting of ?n integers. All these integers are distinct, each value from 11 to ?n appears in the sequence exactly once.

    You are making a sequence of moves. During each move you must take either the leftmost element of the sequence or the rightmost element of the sequence, write it down and remove it from the sequence. Your task is to write down a strictly increasing sequence, and among all such sequences you should take the longest (the length of the sequence is the number of elements in it).

    For example, for the sequence [2,1,5,4,3][2,1,5,4,3] the answer is 44 (you take 22 and the sequence becomes [1,5,4,3][1,5,4,3], then you take the rightmost element 33 and the sequence becomes [1,5,4][1,5,4], then you take 44 and the sequence becomes [1,5][1,5] and then you take 55 and the sequence becomes [1][1], the obtained increasing sequence is [2,3,4,5][2,3,4,5]).

    Input

    The first line of the input contains one integer ?n (1≤?≤2⋅1051≤n≤2⋅105) — the number of elements in ?a.

    The second line of the input contains ?n integers ?1,?2,…,??a1,a2,…,an (1≤??≤?1≤ai≤n), where ??ai is the ?i-th element of ?a. All these integers are pairwise distinct.

    Output

    In the first line of the output print ?k — the maximum number of elements in a strictly increasing sequence you can obtain.

    In the second line print a string ?s of length ?k, where the ?j-th character of this string ??sj should be 'L' if you take the leftmost element during the ?j-th move and 'R' otherwise. If there are multiple answers, you can print any.

     

    Examples

    input

    5 2 1 5 4 3

    output

    4 LRRR

    input

    7 1 3 5 6 7 4 2

    output

    7 LRLRLLL

    input

    3 1 2 3

    output

    3 LLL

    input

    4 1 2 4 3

    output

    4 LLRL

    Note

    The first example is described in the problem statement.

     

    题意:

    给定 n个数,每次只能从两端取,要求现在取的这个数字比上一次大,不可以相等(严格递增)

    如果从左边取 输出 ‘L’ ,如果从右边取 输出 ‘R'

    已知题目中不可能出现相同的数字

     

    思路:

    每次用标记变量 pos 记录两边更大的一个,然后移动 i、j 指针

    ①:当左右两端都大于 pos 时,选择一个较小的,然后进行指针移动;

    ②:当左端大于时,移动 i ;

    ③:当右端大于时,移动 j;

     

    CODE:

    #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <sstream> #include <cstdio> #include <vector> #include <string> #include <cmath> #include <stack> #include <queue> #include <map> #include <deque> #include <set> #define INF 0x3f3f3f3f #define memset(a,b) memset(a,b,sizeof(a)) #define mod 1e6+7; using namespace std; typedef long long LL; const double PI = acos(-1); const int M = 2e5+10; int a[M]; string s; int main() { ios::sync_with_stdio(false); LL minn; LL cnt = 0; int n; cin >> n; for(int i=0; i<n; i++) cin >> a[i]; int i=0,j=n-1; LL pos; if(a[0] < a[n-1]){ s+='L'; pos = a[i]; i++; } else{ s+='R'; pos = a[n-1]; j--; } while(i<=j) { // 注意边界问题,如果当前这个 i 没有判断的话,需要加上 if(i == j){ if(a[i] >= pos) s+='L'; break; } if(a[i] > pos && a[j] > pos) { minn = min(a[i],a[j]); if(minn == a[i]){ pos = a[i]; i++; s+='L'; continue; } else{ pos = a[j]; j--; s+='R'; continue; } } else if(a[i] > pos) { pos = a[i]; i++; s+='L'; continue; } else if(a[j] > pos){ pos = a[j]; j--; s+='R'; continue; } else break; } cnt = s.size(); cout << cnt << endl; cout << s << endl; }

     

    二、 Increasing Subsequence (hard version)

    The only difference between problems C1 and C2 is that all values in input of problem C1 are distinct (this condition may be false for problem C2).

    You are given a sequence ?a consisting of ?n integers.

    You are making a sequence of moves. During each move you must take either the leftmost element of the sequence or the rightmost element of the sequence, write it down and remove it from the sequence. Your task is to write down a strictly increasing sequence, and among all such sequences you should take the longest (the length of the sequence is the number of elements in it).

    For example, for the sequence [1,2,4,3,2][1,2,4,3,2] the answer is 44 (you take 11 and the sequence becomes [2,4,3,2][2,4,3,2], then you take the rightmost element 22 and the sequence becomes [2,4,3][2,4,3], then you take 33 and the sequence becomes [2,4][2,4] and then you take 44 and the sequence becomes [2][2], the obtained increasing sequence is [1,2,3,4][1,2,3,4]).

    Input

    The first line of the input contains one integer ?n (1≤?≤2⋅1051≤n≤2⋅105) — the number of elements in ?a.

    The second line of the input contains ?n integers ?1,?2,…,??a1,a2,…,an (1≤??≤2⋅1051≤ai≤2⋅105), where ??ai is the ?i-th element of ?a.

    Output

    In the first line of the output print ?k — the maximum number of elements in a strictly increasing sequence you can obtain.

    In the second line print a string ?s of length ?k, where the ?j-th character of this string ??sj should be 'L' if you take the leftmost element during the ?j-th move and 'R' otherwise. If there are multiple answers, you can print any.

    Examples

    input

    5 1 2 4 3 2

    output

    4 LRRR

    input

    7 1 3 5 6 5 4 2

    output

    6 LRLRRR

    input

    3 2 2 2

    output

    1 R

    input

    4 1 2 4 3

    output

    4 LLRR

    Note

    The first example is described in the problem statement.


    与第一个不同的地方在于这 n 个数字中,可能存在相同的数字

    处理方法:

    当遇到左右两端相同的时候,要去判断一下从哪个方向取能取到的数量最多

    确定之后只能一直按照这个方向取数(因为左右两端的数相同,当往某一个方向取数时是严格递增的,不能在去相反的方向取数)

     

    CODE:

    #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <sstream> #include <cstdio> #include <vector> #include <string> #include <cmath> #include <stack> #include <queue> #include <map> #include <deque> #include <set> #define INF 0x3f3f3f3f #define memset(a,b) memset(a,b,sizeof(a)) #define mod 1e6+7; using namespace std; typedef long long LL; const double PI = acos(-1); const int M = 2e5+10; int a[M]; string s; int FLAG = 0; // 判断哪个方向能取到的数目更多 int maxLen(int l,int r,int pos) { FLAG = 0; int len1=0,len2=0,pos1=pos; for(int i=l; i<=r; i++){ if(a[i] > pos1){ len1++; pos1 = a[i]; } else break; } pos1 = pos; for(int i=r; i>=l; i--){ if(a[i] > pos1){ pos1 = a[i]; len2++; } else break; } // FLAG 等于1的话,代表从左取数 if(len1>len2){ FLAG = 1; return len1; } else { return len2; } } int main() { ios::sync_with_stdio(false); int n; cin >> n; for(int i=0; i<n; i++) cin >> a[i]; LL pos; int t = 0; s.clear(); int i=0,j=n-1; if(a[0] < a[n-1]) { pos = a[0]; s+='L'; i++; } else if(a[n-1] < a[0]) { s+='R'; pos = a[n-1]; j--; } else { int pos = a[0]; int len = maxLen(i+1,j-1,pos); if(FLAG){ s+='L'; // 只能按照一个方向取数,并且取的数目是 len for(int i=0; i<len; i++) s+='L'; } else { s+='R'; for(int i=0; i<len; i++) s+='R'; } } while(1) { if(i==j) { if(a[i] > pos) s+='L'; break; } if(a[i] > pos && a[j] > pos) { LL minn = min(a[i],a[j]); if(minn == a[i] && a[i] == a[j]) { pos = a[i]; int len = maxLen(i+1,j-1,pos); if(FLAG){ s+='L'; for(int i=0; i<len; i++) s+='L'; } else { s+='R'; for(int i=0; i<len; i++) s+='R'; } break; } if(minn == a[i]) { s+='L'; pos = a[i]; i++; } else if(minn == a[j]) { s+='R'; pos = a[j]; j--; } continue; } if(a[i] > pos) { s+='L'; pos = a[i]; i++; } else if(a[j] > pos) { s+='R'; pos = a[j]; j--; } else break; } LL size1 = s.size(); cout << size1 << endl; cout << s << endl; }

     

    最新回复(0)