E. Character Blocking codeforces1840E

11 篇文章 0 订阅

Problem - E - Codeforces

题目大意:给出两个字符串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;
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

timidcatt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值