제출 #1299446

#제출 시각아이디문제언어결과실행 시간메모리
1299446M_SH_OCrossing (JOI21_crossing)C++20
49 / 100
666 ms18520 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 = 11;

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];


    if (s[0] == s[1] && s[0] == s[2]) {


        set<pair<pll, char>> st, st1;

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

        ll q;
        cin >> q;

        str s1;
        cin >> s1;

        c = s1[0];
        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});
        ll k = 0;
        for (auto i : st1) {
            if (st.find(i) == st.end()) k ++;
        }

        /*for (auto i : st) {
            cout << i.fr.fr << ' ' << i.fr.se << ' ' << i.se << endl;
        }
        cout << endl;

        for (auto i : st1) {
            cout << i.fr.fr << ' ' << i.fr.se << ' ' << i.se << endl;
        }
        cout << endl;*/

        if (k == 0) cout << "Yes" << endl;
        else cout << "No" << endl;



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


            /*pair<pll, char> p_ = *it;
            cout << p_.fr.fr << ' ' << p_.fr.se << ' ' << p_.se << endl;*/

            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);
                    if (st.find(p) == st.end()) k --;
                    if (p.fr.se > r) {
                        pair<pll, char> p1 = p;
                        p1.fr.fr = r+1;
                        if (st.find(p1) == st.end()) k ++;
                        st1.insert(p1);
                    }
                    if (p.fr.fr < l) {
                        p.fr.se = l-1;
                        if (st.find(p) == st.end()) k ++;
                        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);
                    if (st.find(p1) == st.end()) k --;
                    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);
                    if (st.find(p1) == st.end()) k --;
                    l = p1.fr.fr;
                }
            }

            if (st.find({{l, r}, c}) == st.end()) k ++;
            st1.insert({{l, r}, c});


            /*cout << "!!!" << endl;
            for (auto i : st1) {
                cout << i.fr.fr << ' ' << i.fr.se << ' ' << i.se << endl;
            }
            cout << endl;*/

            if (k == 0) cout << "Yes" << endl;
            else cout << "No" << endl;
        }


        return 0;
    }

    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...