Increasing Subsequence (hard version) CodeForces - 1157C2

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

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 aa consisting of nn 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 nn (1≤n≤2⋅1051≤n≤2⋅105) — the number of elements in aa.

The second line of the input contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤2⋅1051≤ai≤2⋅105), where aiai is the ii-th element of aa.

Output

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

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

Examples

input

Copy

5
1 2 4 3 2

output

Copy

4
LRRR

input

Copy

7
1 3 5 6 5 4 2

output

Copy

6
LRLRRR

input

Copy

3
2 2 2

output

Copy

1
R

input

Copy

4
1 2 4 3

output

Copy

4
LLRR

Note

The first example is described in the problem statement.

 

題意:很簡單直觀,就是不斷從左或右邊取一個數按照順序組成一個序列,必須要組成一個嚴格遞增的序列。最後將從左右取數的順序輸出出來,用LR表示左右。

 

分析:題意很直觀,但具體何種情況下取什麼數有點複雜,這裏要分析清楚,什麼時候取左邊的,什麼時候取右邊的?

我們分類討論下整個題目會出現的情況,然後分別制定相應的取數策略:

1. 左右兩個數都比我們上次選擇的數字大,那麼就選左右兩個數中偏小的數

2. 左右兩個數字相等但都比上次所取的數字大,那麼我們要選擇那個嚴格遞增序列較長的那一邊,不難發現,這樣一選,只能一條路走到黑,因爲一旦選擇就會一直選擇下去,那麼另外一邊就不會選擇了,我們要實現的是嚴格遞增序列。

3. 左右兩個數一邊大於上次選擇的數,一邊小於上次選的數,那麼下一個選擇較大的那個數。

4. 左右兩個數都比上次選的小,那麼直接就不選了。

題意理解不難,主要是分類討論要想清楚。

 

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 2e5+10;
int a[maxn];
char ans[maxn];
int top;
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    /*
        1.兩邊都較大 選其中較小的
        2.兩邊一樣大 選其中遞增序列長的
        3.一邊較大 選擇較大的
        4.兩邊都不較大 不選擇
    */
    int l=1,r=n,flag = 0;
    while(1){
        if(l>r)break;
        if(l>n||r<1)break;
        if(a[l]!=a[r]&&a[l]>flag&&a[r]>flag)
        {
            if(a[l]<a[r])
            {
                ans[top++] = 'L';
                flag = a[l];
                l++;
            }
            else
            {
                ans[top++] = 'R';
                flag = a[r];
                r--;
            }
        }
        else if(a[l]==a[r]&&a[l]>flag)
        {
            int lenl=0,lenr=0,last;
            for(int i = r,last = flag;i>=min(l,1);last = a[i],i--)
                if(a[i]>last)lenr++;
                else break;
            for(int i = l,last = flag;i<=max(r,n);last = a[i],i++)
                if(a[i]>last)lenl++;
                else break;

            if(lenl>lenr){
                int tmp = lenl;
                while(lenl)
                {
                    ans[top++] = 'L';
                    lenl--;
                }
                l = l+tmp-1;
                flag = a[l];
            }
            else
            {
                int tmp = lenr;
                while(lenr){
                    ans[top++] = 'R';
                    lenr--;
                }
                r = r-tmp+1;
                flag = a[r];
            }
        }
        else if(a[l]>flag&&a[r]<=flag)
        {
            while(l<=r&&a[l]>flag){
                ans[top++] = 'L';
                flag = a[l];
                l++;
            }
        }
        else if(a[r]>flag&&a[l]<=flag)
        {
            while(r>=l&&a[r]>flag){
                ans[top++] = 'R';
                flag = a[r];
                r--;
            }
        }
        else
        {
            break;
        }
    }
    printf("%d\n",top);
    for(int i=0;i<top;i++)
        putchar(ans[i]);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章