145E - Lucky Queries

Click to show code.


using namespace std;
struct node
{
    int n4, n7;
    int n47, n74;
};
const int NMAX = 1e6 + 11;
int n, a[NMAX];
bool lazy[4 * NMAX];
node seg[4 * NMAX];
node merge(node u, node v)
{
    node ans;
    ans.n4 = u.n4 + v.n4;
    ans.n7 = u.n7 + v.n7;
    ans.n47 = max({u.n4 + v.n47, u.n47 + v.n7});
    ans.n74 = max({u.n7 + v.n74, u.n74 + v.n4});
    return ans;
}
inline node make_leaf(int d) { return {(d == 4), (d == 7), 1, 1}; }
void lazy_propagate(int v, int tl, int tr)
{
    swap(seg[v].n4, seg[v].n7);
    swap(seg[v].n47, seg[v].n74);
    if (tl != tr)
    {
        lazy[2 * v] = !lazy[2 * v];
        lazy[2 * v + 1] = !lazy[2 * v + 1];
    }
    lazy[v] = !lazy[v];
}
void build(int a[], int v, int tl, int tr)
{
    if (tl == tr)
        seg[v] = make_leaf(a[tl]);
    else
    {
        int tm = (tl + tr) / 2;
        build(a, 2 * v, tl, tm);
        build(a, 2 * v + 1, tm + 1, tr);
        seg[v] = merge(seg[2 * v], seg[2 * v + 1]);
    }
}
void update(int v, int tl, int tr, int ql, int qr)
{
    if (lazy[v])
        lazy_propagate(v, tl, tr);
    if (ql > qr)
        return;
    if (tl == ql and tr == qr)
    {
        lazy_propagate(v, tl, tr);
        lazy[v] = false;
    }
    else
    {
        int tm = (tl + tr) / 2;
        update(2 * v, tl, tm, ql, min(tm, qr));
        update(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr);
        seg[v] = merge(seg[2 * v], seg[2 * v + 1]);
    }
}
node query(int v, int tl, int tr, int ql, int qr)
{
    if (lazy[v])
        lazy_propagate(v, tl, tr);
    if (ql > qr)
        return {};
    if (tl == ql and tr == qr)
        return seg[v];
    else
    {
        int tm = (tl + tr) / 2;
        return merge(query(2 * v, tl, tm, ql, min(tm, qr)),
                     query(2 * v + 1, tm + 1, tr, max(tm + 1, ql), qr));
    }
}
int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int q, l, r;
    string s, type;
    cin >> n >> q;
    cin >> s;
    for (int i = 0; i < n; ++i)
        a[i] = s[i] - '0';
    build(a, 1, 0, n - 1);
    while (q--)
    {
        cin >> type;
        if (type == "count")
        {
            node ans = query(1, 0, n - 1, 0, n - 1);
            cout << ans.n47 << endl;
        }
        else
        {
            cin >> l >> r;
            update(1, 0, n - 1, l - 1, r - 1);
        }
    }
    return 0;
}