제출 #1299444

#제출 시각아이디문제언어결과실행 시간메모리
1299444M_SH_OCrossing (JOI21_crossing)C++20
26 / 100
350 ms14100 KiB
/*#pragma GCC optimize("O3")
#pragma GCC optimization("Ofast,unroll-loops")
#pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt")*/
//#include "cheapai.h"
#include <bits/stdc++.h>
/*#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>*/

#define ll long long
#define ll1 long long
#define ull unsigned long long
#define dou long double
#define str string
#define vll vector<ll>
#define vi vector<int>
#define pll pair<ll, ll>
#define vpll vector<pair<ll, ll>>
#define vbool vector<bool>
#define vstr vector<str>
#define vvll vector<vll>
#define pb push_back
#define pf push_front
#define endl "\n"
#define fr first
#define se second
// #define sortcmp(a) sort(a.begin(), a.end(), cmp)
#define sort(a) sort(a.begin(), a.end())
#define reverse(a) reverse(a.begin(), a.end())
#define speed ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define ordered_set tree<ll, null_type, less_equal<ll>, rb_tree_tag, tree_order_statistics_node_update>

using namespace std;
//using namespace __gnu_pbds;

const ll INF = 1e18+7;
const int lg = 20;
const ll MOD = 1e9+7;
//const ll MOD2 = 998244353;

mt19937 rng(1488);
ll randll(ll l, ll r) {
    return uniform_int_distribution<ll>(l, r)(rng);
}

str f(str s, str s1) {
    str res = "";
    for (int i = 0; i < s.size(); i ++) {
        if (s[i] == s1[i]) res += str(1, s[i]);
        else if (s[i] == 'J' && s1[i] == 'O') res += str(1, 'I');
        else if (s[i] == 'O' && s1[i] == 'J') res += str(1, 'I');
        else if (s[i] == 'J' && s1[i] == 'I') res += str(1, 'O');
        else if (s[i] == 'I' && s1[i] == 'J') res += str(1, 'O');
        else res += str(1, 'J');
    }

    return res;
}

ll p = 29;

ll int1(char c){
    if (c == 'J') return 1;
    if (c == 'O') return 2;
    return 3;
}

ull polyh(str s) {
    ull res = 0;
    for (int i = 0; i < s.size(); i ++) {
        res *= p;
        res += int1(s[i]);
    }
    return res;
}

int main() {
    speed;

    ll n;
    cin >> n;
    vstr s(3);
    cin >> s[0];
    cin >> s[1];
    cin >> s[2];

    set<ull> st;
    vstr v1;
    vstr v;
    v.pb(s[0]);
    v.pb(s[1]);
    v.pb(s[2]);

    for (int i = 0; i < v.size(); i ++) {
        ull h = polyh(v[i]);
        if (st.find(h) != st.end()) continue;
        st.insert(h);
        for (auto j : v1) {
            str s1 = f(j, v[i]);
            if (st.find(polyh(s1)) == st.end()) v.pb(s1);
        }
        v1.pb(v[i]);
    }

    /*for (auto i : v1) {
        cout << i << endl;
    }*/

    ll q;
    cin >> q;

    str s1;
    cin >> s1;

    ll res = polyh(s1);

    vector<ull> pow2(n, 1), pref(n+7, 0);
    for (int i = n-2; i >= 0; i --) {
        pow2[i] = pow2[i+1]*p;
    }

    for (int i = 0; i < n; i ++) {
        pref[i+1] = pref[i]+pow2[i];
    }

    set<pair<pll, char>> st1;

    char c = s1[0];
    ll l = 0;
    for (int i =0 ; i < n; i ++) {
        if (s1[i] == c) continue;
        st1.insert({{l, i-1}, c});
        l = i;
        c = s1[i];
    }
    st1.insert({{l, n-1}, c});

    if (st.find(res) != st.end()) cout << "Yes" << endl;
    else cout << "No" << endl;

    while (q --) {
        ll l, r;
        char c;
        cin >> l >> r >> c;
        l --, r --;

        while (st1.size()) {
            auto it = st1.upper_bound({{r, INF}, 'a'});
            if (it == st1.begin()) break;
            auto it1 = it;
            it1 --;
            pair<pll, char> p = *it1;
            //cout << p.fr.fr << ' ' << p.fr.se << ' ' << p.se << endl;
            if (p.fr.se >= l) {
                st1.erase(it1);
                res -= (pref[p.fr.se+1]-pref[p.fr.fr])*int1(p.se);
                if (p.fr.se > r) {
                    pair<pll, char> p1 = p;
                    p1.fr.fr = r+1;
                    //if (st.find(p1) == st.end()) k ++;
                    res += (pref[p1.fr.se+1]-pref[p1.fr.fr])*int1(p1.se);
                    st1.insert(p1);
                }
                if (p.fr.fr < l) {
                    p.fr.se = l-1;
                    res += (pref[p.fr.se+1]-pref[p.fr.fr])*int1(p.se);
                    st1.insert(p);
                    break;
                }
            }
            else break;
        }

        auto it = st1.upper_bound({{r, -INF}, 'a'});
        if (it != st1.end()) {
            pair<pll, char> p1 = *it;
            if (p1.se == c) {
                st1.erase(it);
                res -= (pref[p1.fr.se+1]-pref[p1.fr.fr])*int1(p1.se);
                r = p1.fr.se;
            }
        }

        it = st1.upper_bound({{r, -INF}, 'a'});
        if (it != st1.begin()) {
            it --;
            pair<pll, char> p1 = *it;
            if (p1.se == c) {
                st1.erase(it);
                res -= (pref[p1.fr.se+1]-pref[p1.fr.fr])*int1(p1.se);
                l = p1.fr.fr;
            }
        }

        st1.insert({{l, r}, c});

        res += (pref[r+1]-pref[l])*int1(c);



        //cout << s1 << endl;

        if (st.find(res) != st.end()) cout << "Yes" << endl;
        else cout << "No" << endl;
    }

}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...