Codeforces - Increasing Subsequence(easy & hard version)

一、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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值