我的思路先找有效的LR,记录数量,后续更改如果使得有效的LR数量为0,那么输出yes,否则no 寻找有效的LR就是需要有数字移动需要通过LR这个位置,这个操作我是通过总的区间(分为从左到右移动和从右到左移动) 减去 范围外的独立区间来找的,实现不知道哪里出了问题,望指正。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
void slove()
{
ll n, q, num1 = 0, num2 = 0;
string ss;
cin >> n >> q;
vector <ll> p(n + 1);
for(ll i = 1; i <= n; i ++)
{
cin >> p[i];
}
vector <ll> l1(n + 1, 0), l2(n + 1, 0), r1(n + 1, 0), r2(n + 1, 0);
for(ll i = 1; i <= n; i ++)
{
if(p[i] > i)
{
l1[i] = 1;
r1[p[i]] = 1;// l 小 r 大
num1 ++;
}
}
for(ll i = 2; i <= n; i ++)
{
r1[i] += r1[i - 1];
}
for(ll i = n - 1; i > 1; i --)
{
l1[i] += l1[i + 1];
}
for(ll i = n; i >= 1; i --)
{
if(p[i] < i)
{
l2[i] = 1;
r2[p[i]] = 1;// l 大 r 小
num2++;
}
}
for(ll i = 2; i <= n; i ++)
{
l2[i] += l2[i - 1];
}
for(ll i = n - 1; i > 1; i --)
{
r2[i] += r2[i + 1];
}
cin >> ss;
vector <bool> markk(n);
ll number = 0;
for(ll i = 1; i < n - 1; i ++)
{
if(ss[i] == 'L' && ss[i + 1] == 'R')
{
if((num1 - l1[i + 2] - r1[i + 1]) != 0 || (num2 - l2[i + 1] - r2[i + 2]) != 0)
{
markk[i] = 1;
number ++;
}
}
}
while(q --)
{
ll num;
bool judge = 1;
cin >> num;
if(ss[num - 1] == 'L' && markk[num - 1] == 1)
{
markk[num - 1] = 0;
number --;
}
ss[num - 1] == 'L' ? ss[num - 1] = 'R' : ss[num - 1] = 'L';
if(ss[num - 1] == 'L' && ss[num] == 'R')
{
if((num1 - l1[num + 1] - r1[num]) != 0 || (num2 - l2[num] - r2[num + 1]) != 0)
{
markk[num - 1] = 1;
number ++;
}
}
if(ss[num - 2] == 'L' && ss[num - 1] == 'R')
{
if((num1 - l1[num] - r1[num - 1]) != 0 || (num2 - l2[num - 1] - r2[num]) != 0)
{
markk[num - 2] = 1;
number ++;
}
}
if(number > 0)
{
cout << "NO" << endl;
}
else
{
cout << "YES" << endl;
}
}
return ;
}
int main()
{
ll t = 1;
cin >> t;
while(t --)
{
slove();
}
return 0;
}