Submission #864220

#TimeUsernameProblemLanguageResultExecution timeMemory
864220vjudge1Crossing (JOI21_crossing)C++17
49 / 100
7034 ms61964 KiB
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
#define pb push_back
#define mp make_pair
struct seg2 {
    vi nodes, upd;
    seg2(int sz) {
        nodes.resize(sz*4);
        upd.resize(sz*4,-1);
    }
    seg2() : seg2(0) {}
    int lc(int x) { return x << 1; }
    int rc(int x) { return lc(x) | 1; }
    void pushdown(int x) {
        if (upd[x] != -1) {
            nodes[x] = upd[x];
            if (lc(x) < nodes.size()) nodes[lc(x)] = upd[x];
            if (rc(x) < nodes.size()) nodes[rc(x)] = upd[x];
            upd[x] = -1;
        }
    }
    void update(int l, int r, int x, int xl, int xr, bool b) {
        if (l > r) return;
        pushdown(x);
        if (l == xl && r == xr) {
            upd[x] = b;
        } else {
            int xm = (xl + xr) >> 1;
            update(l, min(r,xm), lc(x), xl, xm, b);
            update(max(xm+1,l), r, rc(x), xm+1, xr, b);
            pushdown(lc(x));
            pushdown(rc(x));
            nodes[x] = nodes[lc(x)] || nodes[rc(x)];
        }
    }
    bool query() {
        pushdown(1);
        return nodes[1];
    }
};
 
struct intervals {
    seg2 tree;
    int sz;
    intervals(int sz) {
        this->sz = sz;
        tree = seg2(sz);
    }
    intervals() : intervals(0) {}
    void add(int l, int r) {
        tree.update(l, r, 1, 0, sz-1, 1);
    }
    void remove(int l, int r) {
        tree.update(l, r, 1, 0, sz-1, 0);
    }
    bool empty() {
        return !tree.query();
    }
};
 
struct seg1 {
    vector<char> orig;
    vector<char> upd;
    intervals wrong;
    seg1(string s) {
        int sz = (int)s.size();
        orig.resize(sz*4,0);
        upd.resize(sz*4,0);
        build(s,1,0,sz-1);
        wrong = intervals(sz);
    }
    int lc(int x) { return x << 1; }
    int rc(int x) { return lc(x) | 1; }
    void build(string &s, int x, int xl, int xr) {
        if (xl == xr) orig[x] = upd[x] = s[xl];
        else {
            int xm = (xl + xr) >> 1;
            build(s,lc(x),xl,xm);
            build(s,rc(x),xm+1,xr);
            if (orig[lc(x)] == orig[rc(x)]) {
                orig[x] = upd[x] = orig[lc(x)];
            }
        }
    }
    void check(int x, int xl, int xr) {
        if (upd[x] != orig[x]) {
            wrong.add(xl, xr);
        } else {
            wrong.remove(xl, xr);
        }
    }
    void pushdown(int x, int xl, int xr) {
        if (xl == xr) return;
        if (upd[x] == '0') return;
        wrong.remove(xl, xr);
        int xm = (xl + xr) >> 1;
        if (lc(x) < upd.size()) {
            upd[lc(x)] = upd[x];
            check(lc(x), xl, xm);
        }
        if (rc(x) < upd.size()) {
            upd[rc(x)] = upd[x];
            check(rc(x), xm+1, xr);
        }
        upd[x] = '0';
    }
    void update(int l, int r, int x, int xl, int xr, char c) {
        if (l > r) return;
        assert(x != 0);
        pushdown(x, xl, xr);
        if (l == xl && r == xr) {
            upd[x] = c;
            check(x, xl, xr);
        } else {
            int xm = (xl + xr) >> 1;
            update(l, min(xm,r), lc(x), xl, xm, c);
            update(max(xm+1,l), r, rc(x), xm+1, xr, c);
        }
    }
};
string cross(string a, string b) {
    string out = a;
    for (int i=0; i<(int)a.size(); i++) {
        if (a[i] != b[i]) {
            out[i] = 'J' + 'O' + 'I' - a[i] - b[i];
        }
    }
    return out;
}
 
int main() {
    cin.tie(0)->sync_with_stdio(0);
    // freopen("in.txt", "r", stdin);
    // freopen("out.txt", "w", stdout);
    int n;
    cin >> n;
    string a, b, c;
    cin >> a >> b >> c;
 
    set<string> V;
    V.insert(a);
    V.insert(b);
    V.insert(c);
    bool upd = true;
    while (upd) {
        upd = false;
        for (auto it1=V.begin(); it1!=V.end(); it1++) {
            for (auto it2=V.begin(); it2!=V.end(); it2++) {
                if (it1 == it2) continue;
                string x = cross(*it1, *it2);
                if (!V.count(x)) {
                    V.insert(x);
                    upd = true;
                }
            }
        }
    }
 
    vector<seg1> trees;
    for (const string &s : V) {
        trees.push_back(seg1(s));
    }
    int q;
    cin >> q;
    string t;
    cin >> t;
    for (int i=0; i<(int)t.size(); i++) {
        for (seg1 &tree : trees) tree.update(i,i,1,0,n-1,t[i]);
    }
    auto output_ans = [&]() {
        bool ans = false;
        for (seg1 &tree : trees) {
            if (tree.wrong.empty()) {
                ans = true;
                break;
            }
        }
        cout << ( ans ? "Yes" : "No" ) << "\n";
    };
    output_ans();
    for (int i=0; i<q; i++) {
        int l, r;
        cin >> l >> r;
        l--, r--;
        char c;
        cin >> c;
        for (seg1 &tree : trees) tree.update(l,r,1,0,n-1,c);
        output_ans();
    }
    return 0;
}

Compilation message (stderr)

Main.cpp: In member function 'void seg2::pushdown(int)':
Main.cpp:22:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   22 |             if (lc(x) < nodes.size()) nodes[lc(x)] = upd[x];
      |                 ~~~~~~^~~~~~~~~~~~~~
Main.cpp:23:23: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   23 |             if (rc(x) < nodes.size()) nodes[rc(x)] = upd[x];
      |                 ~~~~~~^~~~~~~~~~~~~~
Main.cpp: In member function 'void seg1::pushdown(int, int, int)':
Main.cpp:102:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  102 |         if (lc(x) < upd.size()) {
      |             ~~~~~~^~~~~~~~~~~~
Main.cpp:106:19: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<char>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  106 |         if (rc(x) < upd.size()) {
      |             ~~~~~~^~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...