제출 #533852

#제출 시각아이디문제언어결과실행 시간메모리
533852someoneCrossing (JOI21_crossing)C++14
100 / 100
1409 ms56644 KiB
#include <bits/stdc++.h>
#define int long long
using namespace std;
 
const int M = 1 << 18, N = 2 * M;

int n, q, ans = 0, val[3][M];

struct HashLazy {
    set<int> pos;
    int hashval[N], tag_a[N], tag_b[N], pow3[M+1], cumP[M+1], MOD;
    
    HashLazy(int mod) {
        MOD = mod;
        
        pow3[0] = 1;
        for(int i = 1; i <= M; i++)
            pow3[i] = (pow3[i-1] * 3) % MOD;
        for(int i = 1; i <= M; i++)
            cumP[i] = (pow3[i-1] + cumP[i-1]) % MOD;
        
        for(int i = 0; i < 3; i++)
            for(int j = 0; j < 3; j++) {
                int hashing = 0;
                for(int k = 0; k < n; k++)
                    hashing = (hashing * 3 + (i * (val[0][k] + val[1][k] + val[2][k]) + val[j][k]) % 3) % MOD;
                pos.insert(hashing);
            }
    }
 
    inline void updNode(int i, int a, int b, int d, int f) {
        if(a == 0) {
            tag_a[i] = 0;
            tag_b[i] = b;
            hashval[i] = (b * cumP[f - d]) % MOD;
        }
    }
     
    int update(int i, int deb, int fin, int a, int b, int d = 0, int f = M) {
        if(deb <= d && f <= fin) {
            updNode(i, a, b, d, f);
            return hashval[i];
        }
        if(f <= deb || fin <= d)
            return 0;
        
        int med = (d + f) >> 1;
        updNode(i*2, tag_a[i], tag_b[i], d, med);
        updNode(i*2+1, tag_a[i], tag_b[i], med, f);
        
        tag_a[i] = 1;
        tag_b[i] = 0;
        
        int val1 = update(i*2, deb, fin, a, b, d, med),
            val2 = update(i*2+1, deb, fin, a, b, med, f);
        
        hashval[i] = (hashval[i*2] * pow3[f-med] + hashval[i*2+1]) % MOD;
      
        if(deb < med && med < fin)
            return (val1 * pow3[fin-med] + val2) % MOD;
        else
            return max(val1, val2);
    }
    
    bool good() {
        return pos.find(update(1, 0, n, 1, 0)) != pos.end();
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    
    cin >> n;
    
    for(int i = 0; i < 3; i++) {
        for(int j = 0; j < n; j++) {
            char c; cin >> c;
            if(c == 'O')
                val[i][j] = 1;
            else if(c == 'I')
                val[i][j] = 2;
        }
    }
    
    HashLazy a(1e9 + 7), b(1e9 + 9), d(1e9 + 21);
    
    cin >> q;
    for(int i = 0; i < n; i++) {
        char c; cin >> c;
        if(c == 'O') {
            a.update(1, i, i+1, 0, 1);
            b.update(1, i, i+1, 0, 1);
            d.update(1, i, i+1, 0, 1);
        } else if(c == 'I') {
            a.update(1, i, i+1, 0, 2);
            b.update(1, i, i+1, 0, 2);
            d.update(1, i, i+1, 0, 2);
        }
    }
    
    if(a.good() && b.good() && d.good())
        cout << "Yes\n";
    else
        cout << "No\n";
    
    for(int i = 0; i < q; i++) {
        char c;
        int deb, fin;
        cin >> deb >> fin >> c;
        deb--;
        if(c == 'J') {
            a.update(1, deb, fin, 0, 0);
            b.update(1, deb, fin, 0, 0);
            d.update(1, deb, fin, 0, 0);
        } else if(c == 'O') {
            a.update(1, deb, fin, 0, 1);
            b.update(1, deb, fin, 0, 1);
            d.update(1, deb, fin, 0, 1);
        } else if(c == 'I') {
            a.update(1, deb, fin, 0, 2);
            b.update(1, deb, fin, 0, 2);
            d.update(1, deb, fin, 0, 2);
        }
    
        if(a.good() && b.good() && d.good())
            cout << "Yes\n";
        else
            cout << "No\n";
    }
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...