前置知识
解法
对于移动,我们可以无脑进行交换来保证移动,然后将中途交换的位置再交换回去。
通过手摸不难发现,\(p_{i}\) 能移动到 \(i\) 当且仅当 \(s_{\min(i,p_{i}) \sim \max(i,p_{i})}\) 中不含有 LR
子串。
反向考虑,即 LR
子串不被上述区间包含,差分判断即可。
代码
ll a[200010],d[200010];
char s[200010];
int main()
{
ll t,n,m,x,sum,i,j;
cin>>t;
for(j=1;j<=t;j++)
{
cin>>n>>m;
sum=0;
for(i=1;i<=n;i++)
{
cin>>a[i];
d[min(a[i],i)]++;
d[max(a[i],i)]--;
}
for(i=1;i<=n;i++)
{
d[i]+=d[i-1];
}
cin>>(s+1);
for(i=1;i<=n-1;i++)
{
if(s[i]=='L'&&s[i+1]=='R')
{
sum+=(d[i]!=0);
}
}
for(i=1;i<=m;i++)
{
cin>>x;
if(s[x]=='L')
{
s[x]='R';
if(x+1<=n&&s[x+1]=='R')
{
sum-=(d[x]!=0);
}
if(x-1>=1&&s[x-1]=='L')
{
sum+=(d[x-1]!=0);
}
}
else
{
s[x]='L';
if(x+1<=n&&s[x+1]=='R')
{
sum+=(d[x]!=0);
}
if(x-1>=1&&s[x-1]=='L')
{
sum-=(d[x-1]!=0);
}
}
if(sum!=0)
{
cout<<"No"<<endl;
}
else
{
cout<<"Yes"<<endl;
}
}
for(i=1;i<=n;i++)
{
d[i]=0;
}
}
return 0;
}
标签:QED,CF2030D,题解,sum,Favorite,200010,Permutation,ll
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18537906