>Link
>Description
T ≤ 100 , n ≤ 1 0 5 T\le 100, n \le 10^5 T≤100,n≤105
>解题思路
麻掉了TAT 考场被T1卡了就没想后面的题,回来认真看了看没几分钟就想出来了,还是需要调整一下做题的方法,把所有题看了都想一想再开始打TAT(其实还是菜,不然也不会被卡
因为一个数只会出现两次,并且最终数列为回文数列,所以如果我们在前面确定了一个数,另一个数的位置也会确定
手玩一下就会发现,我们拿两个指针 l , r l,r l,r 指当前 a a a 数列的左右端点,操作就是左右端点不断靠近,根据上一行的性质,我们发现在 l , r l,r l,r 中间还有两个指针 l l , r r ll,rr ll,rr, [ l l , r r ] [ll,rr] [ll,rr] 中的数的位置是已经根据前面的操作确定了的,且他们的位置组成一个单峰序列。还没操作但确定了位置的数一定是聚在一起的,根据操作规则和回文的性质易证。
如果 l l l 或 r r r 上的数,它另一个对应的数在 [ l l , r r ] [ll,rr] [ll,rr] 的左右边,说明就是可以操作的,对 l , r , l l , r r l,r,ll,rr l,r,ll,rr 这些指针进行移动,注意要记录下 [ l l , r r ] [ll,rr] [ll,rr] 内的位置,便于后续的操作;否则不能达成。为了让操作的字典序最小,我们就尽量用左操作。
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 500010
using namespace std;
int T, n, m, a[2 * N], l, r, ll, rr, pos[2 * N];
char ans[2 * N];
bool solve ()
{
if (!ll) return 0;
for (int i = 2; i <= n; i++)
{
if (a[l] == a[ll - 1] && l < ll - 1)
{
l++, ll--;
pos[ll] = 2 * n - i + 1;
ans[i] = 'L';
}
else if (a[l] == a[rr + 1] && l < rr + 1)
{
l++, rr++;
pos[rr] = 2 * n - i + 1;
ans[i] = 'L';
}
else if (a[r] == a[ll - 1] && r > ll - 1)
{
r--, ll--;
pos[ll] = 2 * n - i + 1;
ans[i] = 'R';
}
else if (a[r] == a[rr + 1] && r > rr + 1)
{
r--, rr++;
pos[rr] = 2 * n - i + 1;
ans[i] = 'R';
}
else return 0;
}
for (int i = n + 1; i <= 2 * n; i++)
if (pos[ll] <= pos[rr]) ll++, ans[i] = 'L';
else rr--, ans[i] = 'R';
return 1;
}
void work ()
{
scanf ("%d", &n);
for (int i = 1; i <= 2 * n; i++) scanf ("%d", &a[i]);
memset (pos, 0, sizeof (pos));
ll = rr = 0;
for (int i = 2; i <= 2 * n; i++)
if (a[i] == a[1])
{
ll = rr = i;
pos[i] = 2 * n;
break;
}
l = 2, r = 2 * n;
ans[1] = 'L';
if (solve ())
{
for (int i = 1; i <= 2 * n; i++)
putchar (ans[i]);
putchar (10);
return;
}
memset (pos, 0, sizeof (pos));
ll = rr = 0;
for (int i = 1; i < 2 * n; i++)
if (a[i] == a[2 * n])
{
ll = rr = i;
pos[i] = 2 * n;
break;
}
l = 1, r = 2 * n - 1;
ans[1] = 'R';
if (solve ())
{
for (int i = 1; i <= 2 * n; i++)
putchar (ans[i]);
putchar (10);
return;
}
putchar ('-'), putchar ('1'), putchar (10);
}
int main()
{
// freopen ("check.out", "w", stdout);
scanf ("%d", &T);
while (T--)
work ();
return 0;
}