Submission #850504

# Submission time Handle Problem Language Result Execution time Memory
850504 2023-09-16T18:23:51 Z hngwlog Street Lamps (APIO19_street_lamps) C++14
0 / 100
5000 ms 58272 KB
#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define _size(x) (int)x.size()
#define BIT(i, x) ((x >> i) & 1)
#define MASK(n) ((1 << n) - 1)
#define REP(i, n) for (int i = 0, _n = (n); i < _n; i++)
#define FOR(i, a, b) for (int i = a, _b = (b); i <= _b; i++)
#define FORD(i, a, b) for (int i = a, _b = (b); i >= _b; i--)
#define FORB1(i, mask) for (int i = mask; i > 0; i ^= i & - i)
#define FORB0(i, n, mask) for (int i = ((1 << n) - 1) ^ mask; i > 0; i ^= i & - i)
#define FORALL(i, a) for (auto i: a)
#define fastio ios_base::sync_with_stdio(0); cin.tie(0);

struct queryNode {

    string type;
    int id, a, b;
};

int n, q;
string s;
vector<int> a;
vector<queryNode> qu;

namespace subtask1 {

    void main() {

        vector<vector<int>> c(q + 1, vector<int>(n + 1));
        FOR(i, 1, n) c[0][i] = a[i] + c[0][i - 1];
        REP(i, q) {
            FOR(j, 1, n) c[i + 1][j] = c[i][j] - c[i][j - 1];
            if (i && qu[i - 1].type == "toggle") c[i + 1][qu[i - 1].id] = 1 - c[i + 1][qu[i - 1].id];
            FOR(j, 1, n) c[i + 1][j] += c[i + 1][j - 1];
            if (qu[i].type == "query") {
                int a = qu[i].a, b = qu[i].b - 1;
                int ans = 0;
                FOR(j, 1, i + 1) ans += (c[j][b] - c[j][a - 1] == b - a + 1);
                cout << ans << '\n';
            }
        }
    }
}

bool checkSub2() {

    REP(i, q) {
        if (qu[i].type == "toggle") continue;
        if (qu[i].b - qu[i].a != 1) return false;
    }
    return true;
}

namespace subtask2 {

    void main() {

        vector<int> ans(n + 1), in(n + 1, - 1);
        FOR(i, 1, n) if (a[i] == 1) in[i] = 1;
        REP(i, q) {
            if (i && qu[i - 1].type == "toggle") {
                int id  = qu[i - 1].id;
                if (!a[id]) {
                    a[id] = 1 - a[id];
                    in[id] = i + 1;
                }
                else {
                    a[id] = 0;
                    ans[id] += (i + 1) - in[id];
                    in[id] = - 1;
                }
            }
            if (qu[i].type == "query") cout << ans[qu[i].a] + (in[qu[i].a] != - 1 ? i + 1 - in[qu[i].a] + 1 : 0) << '\n';
        }
    }
}

bool checkSub3() {

    vector<int> b(n + 1);
    FOR(i, 1, n) b[i] = a[i];
    REP(i, q) {
        if (qu[i].type == "toggle") {
            int id = qu[i].id;
            if (b[id]) return false;
            b[id] = 1 - b[id];
        }
    }
    return true;
}

namespace subtask3 {

    const int inf = 1e9;

    struct segTree {

        vector<int> ST;

        void init(int n) {

            ST.resize(4 * n + 4);
        }

        void update(int id, int l, int r, int pos, int val) {

            if (pos < l || r < pos) return ;
            if (l == r) {
                ST[id] = val;
                return ;
            }
            int mid = (l + r) / 2;
            update(id * 2, l, mid, pos, val);
            update(id * 2 + 1, mid + 1, r, pos, val);
            ST[id] = max(ST[id * 2], ST[id * 2 + 1]);
        }

        int get(int id, int l, int r, int u, int v) {

            if (r < u || v < l) return 0;
            if (u <= l && r <= v) return ST[id];
            int mid = (l + r) / 2;
            return max(get(id * 2, l, mid, u, v), get(id * 2 + 1, mid + 1, r, u, v));
        }
    } st;

    void main() {

        st.init(n);
        FOR(i, 1, n) {
            if (a[i]) st.update(1, 1, n, i, 1);
            else st.update(1, 1, n, i, inf);
        }
        REP(i, q) {
            if (qu[i].type == "toggle") {
                int id = qu[i].id;
                st.update(1, 1, n, id, i + 2);
            }
            if (qu[i].type == "query") {
                int a = qu[i].a, b = qu[i].b - 1;
                int value = st.get(1, 1, n, a, b);
                if (value == inf) cout << 0 << '\n';
                else cout << i + 1 - value + 1 << '\n';
            }
        }
    }
}

bool checkSub4() {

    int cnt = 0;
    REP(i, q) {
        if (qu[i].type == "toggle" && cnt) return false;
        cnt += (qu[i].type == "query");
    }
    return true;
}

namespace subtask4 {

    struct fenTree {

        int n;
        vector<int> bit;

        void init(int sz) {

            bit.resize(sz + 1);
            n = sz;
        }

        void update(int pos, int val) {

            while (pos <= n) {
                bit[pos] += val;
                pos += pos & - pos;
            }
        }

        int get(int pos) {

            int res = 0;
            while (pos) {
                res += bit[pos];
                pos -= pos & - pos;
            }
            return res;
        }
    } ft;

    void main() {

        map<pair<int, int>, int> in;
        set<int> st;
        int pos = - 1;
        FOR(i, 1, n) {
            if (!a[i]) {
                if (pos != - 1) {
                    in[{pos, i - 1}] = 1;
                    pos = - 1;
                }
                st.insert(i);
            }
            if (pos == - 1 && a[i]) pos = i;
        }
        if (pos) in[{pos, n}] = 1;
        vector<pair<pair<int, int>, int>> g;
        FOR(i, 1, q - 1) {
            if (qu[i - 1].type == "toggle") {
                int id = qu[i - 1].id;
                auto it = st.lower_bound(id);
                int l = - 1, r = - 1;
                if (it == st.end()) r = n;
                else r = *it - 1;
                if (it == st.begin()) l = 1;
                else {
                    it--;
                    l = *it + 1;
                }
                if (a[id]) {
                    g.push_back({{l, r}, i - in[{l, r}] + 1});
                    in.erase({l, r});
                    if (l <= id - 1) in[{l, id - 1}] = i + 1;
                    if (id + 1 <= r) in[{id + 1, r}] = i + 1;
                    st.insert(id);
                }
                else {
                    it = st.upper_bound(id);
                    if (it == st.end()) r = n;
                    else r = *it - 1;
                    if (l <= id - 1) {
                        g.push_back({{l, id - 1}, i - in[{l, id - 1}] + 1});
                        in.erase({l, id - 1});
                    }
                    if (id + 1 <= r) {
                        g.push_back({{id + 1, r}, i - in[{id + 1, r}] + 1});
                        in.erase({id + 1, r});
                    }
                    in[{l, r}] = i + 1;
                    st.erase(id);
                }
                a[id] = 1 - a[id];
            }
            if (qu[i].type == "query") break;
        }
        sort(g.begin(), g.end(), [&] (const pair<pair<int, int>, int> a, pair<pair<int, int>, int> b) { return a.fi.fi < b.fi.fi; });
        vector<int> ask;
        REP(i, q) {
            if (qu[i].type == "toggle") continue;
            ask.push_back(i);
        }
        sort(ask.begin(), ask.end(), [&] (const int i, int j) { return qu[i].a < qu[j].a; });
        vector<int> ans(q);
        ft.init(n);
        int i = 0;
        FORALL(id, ask) {
            while (i < _size(g) && g[i].fi.fi <= qu[id].a) {
                ft.update(g[i].fi.se, g[i].se);
                i++;
            }
            ans[id] += ft.get(n) - ft.get(qu[id].b - 2);
        }
        vector<int> vtx;
        FOR(i, 1, n) if (!a[i]) vtx.push_back(i);
        int cnt = 0;
        REP(i, q) {
            if (qu[i].type == "toggle") continue;
            if (!_size(vtx)) cout << ans[i] + i + 1 - in[{1, n}] + 1 << '\n';
            else {
                pos = lower_bound(vtx.begin(), vtx.end(), qu[i].a) - vtx.begin();
                if (pos == _size(vtx) || vtx[pos] > qu[i].b - 1) {
                    int l = (pos > 0 ? vtx[pos - 1] + 1 : 1);
                    int r = (pos == _size(vtx) ? n : vtx[pos] - 1);
                    cout << ans[i] + i + 1 - in[{l, r}] + 1 << '\n';
                }
                else cout << ans[i] << '\n';
            }
        }
    }
}

namespace subtask5 {

    struct fenTree {

        vector<int> bit;

        void reset(int sz) {

            n = sz;
            bit.clear();
            bit.resize(n + 1);
        }

        void update(int pos, int val) {

            while (pos <= n) {
                bit[pos] += val;
                pos += pos & - pos;
            }
        }

        int get(int pos) {

            int res = 0;
            while (pos) {
                res += bit[pos];
                pos -= pos & - pos;
            }
            return res;
        }
    } ft;

    void main() {

        /***
            chia thanh sqrt(q) block
            duyet trong block
                neu la "toggle" thi update nhu bthg
                con khong duyet lai cac doan moi them
        */

        set<int> st;
        vector<pair<int, int>> cost;
        int pos = - 1;
        FOR(i, 1, n) {
            if (!a[i]) {
                if (pos != - 1) {
                    cost.push_back({pos, i - 1});
                    pos = - 1;
                }
                st.insert(i);
            }
            if (pos == - 1 && a[i]) pos = i;
        }
        if (pos != - 1) cost.push_back({pos, n});

        /***

        */
        vector<int> b(n + 1);
        FOR(i, 1, n) b[i] = a[i];
        REP(i, q) {
            if (qu[i].type == "query") continue;
            int id = qu[i].id;
            auto it = st.lower_bound(id);
            int l = - 1, r = - 1;
            if (it == st.end()) r = n;
            else r = *it - 1;
            if (it == st.begin()) l = 1;
            else {
                it--;
                l = *it + 1;
            }
            if (b[id]) {
                if (l <= id - 1) cost.push_back({l, id - 1});
                if (id + 1 <= r) cost.push_back({id + 1, r});
                st.insert(id);
            }
            else {
                it = st.upper_bound(id);
                if (it == st.end()) r = n;
                else r = *it - 1;
                if (l <= id - 1)
                cost.push_back({l, r});
                st.erase(id);
            }
            b[id] = 1 - b[id];
        }
        sort(cost.begin(), cost.end());
        cost.resize(unique(cost.begin(), cost.end()) - cost.begin());
        vector<vector<int>> adj(q);
        while (_size(st)) st.erase(st.begin());
        FOR(i, 1, n) {
            b[i] = a[i];
            if (!b[i]) st.insert(i);
        }
        REP(i, q) {
            if (qu[i].type == "query") continue;
            int id = qu[i].id;
            auto it = st.lower_bound(id);
            int l = - 1, r = - 1;
            if (it == st.end()) r = n;
            else r = *it - 1;
            if (it == st.begin()) l = 1;
            else {
                it--;
                l = *it + 1;
            }
            if (b[id]) {
                adj[i].push_back(lower_bound(cost.begin(), cost.end(), make_pair(l, r)) - cost.begin());
                if (l <= id - 1) adj[i].push_back(lower_bound(cost.begin(), cost.end(), make_pair(l, id - 1)) - cost.begin());
                if (id + 1 <= r) adj[i].push_back(lower_bound(cost.begin(), cost.end(), make_pair(id + 1, r)) - cost.begin());
                st.insert(id);
            }
            else {
                it = st.upper_bound(id);
                if (it == st.end()) r = n;
                else r = *it - 1;
                if (l <= id - 1) adj[i].push_back(lower_bound(cost.begin(), cost.end(), make_pair(l, id - 1)) - cost.begin());
                if (id + 1 <= r) adj[i].push_back(lower_bound(cost.begin(), cost.end(), make_pair(id + 1, r)) - cost.begin());
                adj[i].push_back(lower_bound(cost.begin(), cost.end(), make_pair(l, r)) - cost.begin());
                st.erase(id);
            }
            b[id] = 1 - b[id];
        }
        while (_size(st)) st.erase(st.begin());
        vector<int> in(_size(cost));
        pos = - 1;
        FOR(i, 1, n) {
            if (!a[i]) {
                if (pos != - 1) {
                    in[lower_bound(cost.begin(), cost.end(), make_pair(pos, i - 1)) - cost.begin()] = 1;
                    pos = - 1;
                }
                st.insert(i);
            }
            if (pos == - 1 && a[i]) pos = i;
        }
        if (pos != - 1) in[lower_bound(cost.begin(), cost.end(), make_pair(pos, n)) - cost.begin()] = 1;

        /***

        */

        int blockSz = sqrt(q);
        int cnt = q / blockSz + (q % blockSz ? 1 : 0);
        vector<int> ans(q);
        vector<pair<int, int>> g;
        REP(t, cnt) {
            int l = t * blockSz, r = min(q - 1, (t + 1) * blockSz - 1);
            vector<int> ask, change;
            FOR(i, l, r) if (qu[i].type == "query") ask.push_back(i); else change.push_back(i);
            sort(ask.begin(), ask.end(), [&] (const int i, int j) { return qu[i].a < qu[j].a; });
            sort(g.begin(), g.end(), [&] (const pair<int, int> a, pair<int, int> b) { return cost[a.fi].fi < cost[b.fi].fi; });
            ft.reset(n);
            int j = 0;
            FORALL(id, ask) {
                while (j < _size(g) && cost[g[j].fi].fi <= qu[id].a) {
                    ft.update(n - cost[g[j].fi].se + 1, g[j].se);
                    j++;
                }
                vector<int> sav_vtx;
                vector<pair<int, int>> sav_in, _g;
                FORALL(i, change) {
                    if (i > id) break;
                    int _id = qu[i].id;
                    auto it = st.lower_bound(_id);
                    int l = - 1, r = - 1;
                    if (it == st.end()) r = n;
                    else r = *it - 1;
                    if (it == st.begin()) l = 1;
                    else {
                        it--;
                        l = *it + 1;
                    }
                    int cnt = 0;
                    if (a[_id]) {
                        _g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt]] + 1});
                        sav_in.push_back({adj[i][cnt], - in[adj[i][cnt]]});
                        if (l <= _id - 1) {
                            cnt++;
                            in[adj[i][cnt]] = i + 2;
                            sav_in.push_back({adj[i][cnt], i + 1});
                        }
                        if (_id + 1 <= r) {
                            cnt++;
                            in[adj[i][cnt]] = i + 2;
                            sav_in.push_back({adj[i][cnt], i + 1});
                        }
                        st.insert(_id);
                        sav_vtx.push_back(_id);
                    }
                    else {
                        it = st.upper_bound(_id);
                        if (it == st.end()) r = n;
                        else r = *it - 1;
                        if (l <= _id - 1) {
                            _g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt]] + 1});
                            sav_in.push_back({adj[i][cnt], - in[adj[i][cnt]]});
                            cnt++;
                        }
                        if (_id + 1 <= r) {
                            _g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt]] + 1});
                            sav_in.push_back({adj[i][cnt], - in[adj[i][cnt]]});
                            cnt++;
                        }
                        in[adj[i][cnt]] = i + 2;
                        sav_in.push_back({adj[i][cnt], i + 2});
                        st.erase(_id);
                        sav_vtx.push_back(- _id);
                    }
                    a[_id] = 1 - a[_id];
                }
                int res = ft.get(n - (qu[id].b - 1) + 1);
                FORALL(e, _g) if (cost[e.fi].fi <= qu[id].a && cost[e.fi].se >= qu[id].b - 1) res += e.se;
                auto it = st.lower_bound(qu[id].a);
                if (it == st.end() || *it > qu[id].b - 1) {
                    int pos = - 1;
                    if (it == st.begin()) pos = 1;
                    else {
                        it--;
                        pos = *it + 1;
                        it++;
                    }
                    int rpos = - 1;
                    if (it == st.end()) rpos = n;
                    else rpos = *it - 1;
                    res += id + 1 - in[lower_bound(cost.begin(), cost.end(), make_pair(pos, rpos)) - cost.begin()] + 1;
                }
                ans[id] = res;
                FORD(i, _size(sav_in) - 1, 0) in[sav_in[i].fi] = abs(sav_in[i].se);
                FORD(i, _size(sav_vtx) - 1, 0) {
                    int pos = sav_vtx[i];
                    a[abs(pos)] = 1 - a[abs(pos)];
                    if (pos < 0) st.insert(- pos);
                    else st.erase(pos);
                }
            }
            FOR(i, l, r) {
                if (qu[i].type == "query") continue;
                int id = qu[i].id;
                auto it = st.lower_bound(id);
                int l = - 1, r = - 1;
                if (it == st.end()) r = n;
                else r = *it - 1;
                if (it == st.begin()) l = 1;
                else {
                    it--;
                    l = *it + 1;
                }
                int cnt = 0;
                if (a[id]) {
                    g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt]] + 1});
                    if (l <= id - 1) in[adj[i][++cnt]] = i + 2;
                    if (id + 1 <= r) in[adj[i][++cnt]] = i + 2;
                    st.insert(id);
                }
                else {
                    it = st.upper_bound(id);
                    if (it == st.end()) r = n;
                    else r = *it - 1;
                    if (l <= id - 1) g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt++]] + 1});
                    if (id + 1 <= r) g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt++]] + 1});
                    in[adj[i][cnt]] = i + 2;
                    st.erase(id);
                }
                a[id] = 1 - a[id];
            }
        }
        REP(i, q) if (qu[i].type == "query") cout << ans[i] << '\n';
    }
}

int main() {
    fastio;
  
    cin >> n >> q;
    cin >> s;
    a.resize(n + 1);
    FOR(i, 1, n) a[i] = s[i - 1] - '0';
    qu.resize(q);
    REP(i, q) {
        cin >> qu[i].type;
        if (qu[i].type == "toggle") cin >> qu[i].id;
        else cin >> qu[i].a >> qu[i].b;
    }
  	subtask5::main();
    return 0;
}

Compilation message

street_lamps.cpp: In function 'void subtask4::main()':
street_lamps.cpp:268:13: warning: unused variable 'cnt' [-Wunused-variable]
  268 |         int cnt = 0;
      |             ^~~
street_lamps.cpp: In function 'void subtask5::main()':
street_lamps.cpp:546:85: warning: operation on 'cnt' may be undefined [-Wsequence-point]
  546 |                     if (l <= id - 1) g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt++]] + 1});
      |                                                                                  ~~~^~
street_lamps.cpp:547:85: warning: operation on 'cnt' may be undefined [-Wsequence-point]
  547 |                     if (id + 1 <= r) g.push_back({adj[i][cnt], i + 1 - in[adj[i][cnt++]] + 1});
      |                                                                                  ~~~^~
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Incorrect 1 ms 344 KB Output isn't correct
3 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Execution timed out 5034 ms 30468 KB Time limit exceeded
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 3 ms 600 KB Output is correct
2 Correct 3 ms 600 KB Output is correct
3 Correct 2 ms 600 KB Output is correct
4 Correct 1 ms 348 KB Output is correct
5 Execution timed out 5056 ms 58272 KB Time limit exceeded
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 1 ms 344 KB Output is correct
2 Correct 1 ms 344 KB Output is correct
3 Incorrect 2 ms 600 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 0 ms 344 KB Output is correct
2 Incorrect 1 ms 344 KB Output isn't correct
3 Halted 0 ms 0 KB -