题目大意:给出两个字符串s1,s2,有3种操作,操作1可以锁定一个位置上的字母持续t次操作(包括这次操作),在之后的t-1次操作内,所有操作对其无效,操作2可以交换任意两个没有被锁定的字母,操作3询问除被锁定的位置外,两个字符串是否相等,一共q次操作
1<=t,q<=2e5;字符串长度<=2e5
思路:如果要判断两个字符串是否相等,那么直接判断的最差时间复杂度是O(n),所以我们考虑如何维护当前字符串是否相等的状态,我们记录初始两字符串不等的位置数dif,然后发现锁定操作是按时间顺序锁定和解锁的,且题目确保了不会锁定已锁定的字母,所以我们可以用栈记录被锁定的位置,和该位置的解锁时间,每次操作前先将所有到了解锁时间的位置解锁,然后每锁定一个原先不等的位置,dif-1,在交换时,如果交换前对应位置字母相等,交换后不等,dif+1,反之dif-1,最后只要判断dif是否唯0即可知道是否相等
//#include<__msvc_all_public_headers.hpp>
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
typedef long long ll;
int main()
{
cin.tie(0);
cout.tie(0);
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
int n;
string s1, s2;
cin >> s1 >> s2;
ll t, q;
cin >> t >> q;
n = s1.length();
int dif = 0;
for (int i = 1; i <= n; i++)
{
if (s1[i - 1] != s2[i - 1])
{
dif++;
}
}
queue<pair<int, int>>qu;
for (int i = 1; i <= q; i++)
{
while (!qu.empty()&&qu.front().second <= i)
{
dif++;
qu.pop();
}
int op;
cin >> op;
if (op == 1)
{
int it;
cin >> it;
if (s1[it - 1] != s2[it - 1])
{
qu.push(make_pair(it, i + t));
dif--;
}
}
else if (op == 2)
{
int so1, it1, so2, it2;
cin >> so1 >> it1 >> so2 >> it2;
bool temp = (s1[it1 - 1] == s2[it1 - 1]);
bool temp2 = (s1[it2 - 1] == s2[it2 - 1]);
if (so1 == 1 && so2 == 1)
{
swap(s1[it1 - 1], s1[it2 - 1]);
}
if (so1 == 1 && so2 == 2)
{
swap(s1[it1 - 1], s2[it2 - 1]);
}
if (so1 == 2 && so2 == 1)
{
swap(s2[it1 - 1], s1[it2 - 1]);
}
if (so1 == 2 && so2 == 2)
{
swap(s2[it1 - 1], s2[it2 - 1]);
}
if (temp && s1[it1 - 1] != s2[it1 - 1])
{
dif++;
}
if (temp2 && s1[it2 - 1] != s2[it2 - 1])
{
dif++;
}
if (!temp && s1[it1 - 1] == s2[it1 - 1])
{
dif--;
}
if (!temp2 && s1[it2 - 1] == s2[it2 - 1])
{
dif--;
}
}
else
{
cout << (!dif ? "YES" : "NO") << endl;
}
}
}
return 0;
}