Submission #1300225

#TimeUsernameProblemLanguageResultExecution timeMemory
1300225mduchelloCrossing (JOI21_crossing)C++20
100 / 100
399 ms28404 KiB
#include<bits/stdc++.h>

using namespace std;

//=====================================================================================================================================

#define ll long long
#define ld long double
#define fi first
#define se second
#define pb push_back
#define pll pair<ll, ll>
#define pli pair<ll, int>
#define pil pair<int, ll>
#define pii pair<int, int>
#define BIT(i, mask) ((mask >> (i)) & 1)
#define DAOBIT(i, mask) ((mask ^ (1 << i)))
#define OFFBIT(i, mask) ((mask & ~(1 << (i))))
#define ONBIT(i, mask) ((mask | (1 << (i))))

//=====================================================================================================================================

const int N = 1e6 + 7;
const ll mod = 1e9 + 6;
const ll MOD = 1e9 + 7;
const ll inf = 1e18;


//=====================================================================================================================================

void fre(){
    freopen("ENCHANTING.INP", "r", stdin);
    freopen("ENCHANTING.out", "w", stdout);
}
ll gcd(ll a, ll b){
    return b ? gcd(b, a % b) : a;
}

ll lcm(ll a, ll b){
    return (a / gcd(a, b)) * b;
}
int n;
string S1, S2, S3;
string T;
int q, L[N], R[N];
char C[N];
char nxt[100][100], ch[] = {'J', 'O', 'I'};
const ll base1 = 137;
const ll base2 = 277;
const ll MOD1 = 127657753, MOD2 = 987654319;
namespace subfull
{
	vector<pll> spw;
	vector<ll> lazy;
	vector<pll> sum;
	pll cal(int l, int r)
	{
		return {(spw[r].fi - spw[l - 1].fi + MOD1) % MOD1, (spw[r].se - spw[l - 1].se + MOD2) % MOD2};
	}
	pll get_hash(string s)
	{
		pll ans = {0, 0};
		ll pw1 = 1, pw2 = 1;
		for (int i = 1; i <= n; i++)
		{
			ans.fi = (ans.fi + (s[i] - 'A' + 1) * pw1) % MOD1;
			ans.se = (ans.se + (s[i] - 'A' + 1) * pw2) % MOD2;
			pw1 = pw1 * base1 % MOD1;
			pw2 = pw2 * base2 % MOD2;
		}
		return ans;
	}
	string combine(string S, string T)
	{
		string ans = "";
		ans += " ";
		for (int i = 1; i <= n; i++)
		{
			char cs = S[i], ct = T[i];
			ans += nxt[cs][ct];
		}
		return ans;
	}
	string str[10];
	vector<pll> hs(10);
	void push(int k, int l, int r, ll lz)
	{
		lazy[k] = lz;
		pll p = cal(l, r);
		sum[k].fi = lz * p.fi % MOD1;
		sum[k].se = lz * p.se % MOD2;
	}
	void down(int k, int l, int r)
	{
		if (lazy[k])
		{
			int mid = (l + r) >> 1;
			push(k << 1, l, mid, lazy[k]);
			push(k << 1 | 1, mid + 1, r, lazy[k]);
			lazy[k] = 0;
		}
	}
	void update(int l, int r, int u, int v, ll val, int k = 1)
	{
		if (l > v || r < u)
			return;
		if (u <= l && r <= v)
		{
			push(k, l, r, val);
			return;
		}
		down(k, l, r);
		int mid = (l + r) >> 1;
		update(l, mid, u, v, val, k << 1);
		update(mid + 1, r, u, v, val, k << 1 | 1);
		sum[k].fi = (sum[k << 1].fi + sum[k << 1 | 1].fi) % MOD1;
		sum[k].se = (sum[k << 1].se + sum[k << 1 | 1].se) % MOD2;
	}
	pll get(int l, int r, int u, int v, int k = 1)
	{
		if (l > v || r < u)
			return {0, 0};
		if (u <= l && r <= v)
			return sum[k];
		down(k, l, r);
		int mid = (l + r) >> 1;
		pll getL = get(l, mid, u, v, k << 1);
		pll getR = get(mid + 1, r, u, v, k << 1 | 1);
		return {(getL.fi + getR.fi) % MOD1, (getL.se + getR.se) % MOD2};
	}
	bool check_ans()
	{
		pll cur = get(1, n, 1, n);
		/// debug(cur);
		for (int i = 1; i <= 9; i++)
			if (hs[i] == cur)
				return true;
		return false;
	}
	void solve()
	{
		spw.assign(n + 1, pll(0, 0));
		lazy.resize(4 * n + 5);
		sum.resize(4 * n + 5);
		S1 = ' ' + S1;
		S2 = ' ' + S2;
		S3 = ' ' + S3;
		T = ' ' + T;
		ll pw1 = 1, pw2 = 1;
		for (int i = 1; i <= n; i++)
		{
			spw[i].fi = (spw[i - 1].fi + pw1) % MOD1;
			spw[i].se = (spw[i - 1].se + pw2) % MOD2;
			pw1 = pw1 * base1 % MOD1;
			pw2 = pw2 * base2 % MOD2;
		}
		str[1] = S1;
		str[2] = S2;
		str[3] = S3;
		str[4] = combine(S1, S2);
		str[5] = combine(S1, S3);
		str[6] = combine(S2, S3);
		str[7] = combine(str[4], S3);
		str[8] = combine(str[5], S2);
		str[9] = combine(str[6], S1);

		for (int i = 1; i <= 9; i++)
			hs[i] = get_hash(str[i]);
//		 for (int i = 1; i <= 9; i++)
//		 	cout << str[i] << ' ' << hs[i].fi << ' ' << hs[i].se << '\n';
		for (int i = 1; i <= n; i++)
			update(1, n, i, i, T[i] - 'A' + 1);
		if (check_ans())
			cout << "Yes" << '\n';
		else
			cout << "No" << '\n';
		for (int i = 1; i <= q; i++)
		{
			update(1, n, L[i], R[i], C[i] - 'A' + 1);
			if (check_ans())
				cout << "Yes" << '\n';
			else
				cout << "No" << '\n';
		}
	}
}

//=====================================================================================================================================

int main(){
    cin.tie(0)->sync_with_stdio(0);
    // fre();
    cin >> n;
	cin >> S1 >> S2 >> S3;
	cin >> q;
	cin >> T;
	for (int i = 1; i <= q; i++)
	{
		cin >> L[i] >> R[i] >> C[i];
	}
	for (int i = 0; i < 3; i++)
	{
		char c = ch[i];
		nxt[c][c] = c;
		for (int j = i + 1; j < 3; j++){
			int id = 3 - (i + j);
			nxt[ch[i]][ch[j]] = nxt[ch[j]][ch[i]] = ch[id];
		}
	}
	subfull::solve();
    return 0;
}

Compilation message (stderr)

Main.cpp: In function 'void fre()':
Main.cpp:32:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   32 |     freopen("ENCHANTING.INP", "r", stdin);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Main.cpp:33:12: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   33 |     freopen("ENCHANTING.out", "w", stdout);
      |     ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...