https://codeforces.com/problemset/problem/1157/C2
思路:
比较明显的是优先拿两边中能拿的小的那一个。什么叫能拿的?就是不能小于等于上一个拿出去的数。
一个特殊的情况就是两者相等。这个情况下其实只会跑一边跑到不能再拿为止。可以考虑此时两边分别跑到底,最后取个最大的。开始没这么想。开始想的就是预处理前后缀处理每个点能到的最远长度。然后O1判断。
suf:前往后跑递减
pre:后往前跑递减
模拟的一个细节就是所有都不符合的情况要else {break;}
#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<cstdio>
#include<algorithm>
#define debug(a) cout<<#a<<"="<<a<<endl;
using namespace std;
const int maxn=2e5+1000;
typedef long long LL;
inline LL read(){LL x=0,f=1;char ch=getchar(); while (!isdigit(ch)){if (ch=='-') f=-1;ch=getchar();}while (isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;}
LL a[maxn],pre[maxn],suf[maxn],tot=0;
char ans[maxn];
int main(void)
{
cin.tie(0);std::ios::sync_with_stdio(false);
LL n;cin>>n;
for(LL i=1;i<=n;i++) cin>>a[i];
a[0]=0x3f3f3f3f;a[n+1]=-0x3f3f3f3f;
for(LL i=1;i<=n;i++){
if(a[i-1]>a[i]) suf[i]=suf[i-1]+1;
else suf[i]=1;
}
for(LL i=n;i>=1;i--){
if(a[i]<a[i+1]) pre[i]=pre[i+1]+1;
else pre[i]=1;
}
LL l=1,r=n;
LL last=-1;
while(l<=r){
if(l==r){
if(a[r]>last) ans[++tot]='R';
break;
}
else if(last>a[l]&&last>a[r]){
break;
}
else if(last<a[l]&&last>=a[r]){
ans[++tot]='L';
last=a[l];
l++;
}
else if(last>=a[l]&&last<a[r]){
ans[++tot]='R';
last=a[r];
r--;
}
else if(last<a[l]&&a[l]<a[r]){
ans[++tot]='L';
last=a[l];
l++;
}
else if(last<a[r]&&a[l]>a[r]){
ans[++tot]='R';
last=a[r];
r--;
}
else if(a[l]==a[r]){
if(pre[l]>suf[r]){
while(a[l]<a[l+1]&&l<r){
ans[++tot]='L';
l++;
}
ans[++tot]='L';
break;
}
else if(pre[l]<=suf[r]){
while(a[r-1]>a[r]&&r>l){
ans[++tot]='R';
r--;
}
ans[++tot]='R';
break;
}
}
else break;
}
cout<<tot<<"\n";
for(LL i=1;i<=tot;i++){
cout<<ans[i];
}
cout<<"\n";
return 0;
}