제출 #935256

#제출 시각아이디문제언어결과실행 시간메모리
935256peterandvoi가로등 (APIO19_street_lamps)C++17
100 / 100
2197 ms217040 KiB
#include <bits/stdc++.h>

using namespace std;

#ifdef ngu
#include "debug.h"
#else
#define debug(...) 42
#endif

const int N = (int) 3e5 + 5;

int n, q;
int t[N], l[N], r[N], p[N];
string s;
vector<int> f[N], tree[N];
vector<tuple<int, int, int>> seg[N];

void fake_get(int u, int v) {
    for (int x = u; x > 0; x -= x & -x) {
        for (int y = v; y <= n; y += y & -y) {
            tree[x].emplace_back(y);
        }
    }
}

void upd(int u, int v, int delta) {
    for (int x = u; x <= n; x += x & -x) {
        for (int y = upper_bound(tree[x].begin(), tree[x].end(), v) - tree[x].begin(); y > 0; y -= y & -y) {
            f[x][y] += delta;
        }
    }
}

int get(int u, int v) {
    int res = 0;
    for (int x = u; x > 0; x -= x & -x) {
        for (int y = lower_bound(tree[x].begin(), tree[x].end(), v) - tree[x].begin() + 1; y <= (int) tree[x].size(); y += y & -y) {
            res += f[x][y];
        }
    }
    return res;
}

namespace ft {
    int tree[N];

    void upd(int i, int x) {
        for (; i <= n; i += i & -i) {
            tree[i] += x;
        }
    }

    int get(int i) {
        int res = 0;
        for (; i > 0; i -= i & -i) {
            res += tree[i];
        }
        return res;
    }

    int get(int l, int r) {
        return get(r) - get(l - 1);
    }

    void reset() {
        memset(tree, 0, sizeof(tree));
    }
}

map<pair<int, int>, int> m;

void del(int l, int r, int cur, bool prep) {
    if (l <= r) {
        if (prep) {
            seg[cur].emplace_back(l, r, cur - m[{l, r}]);
        }
        m.erase({l, r});
    }
}

void add(int l, int r, int cur) {
    if (l <= r) {
        m[{l, r}] = cur;
    }
}

bool check(int l, int r) {
    return ft::get(l, r) == r - l + 1;
}

int findL(int i) {
    int l = 1, r = i - 1, res = i;
    while (l <= r) {
        int mid = l + r >> 1;
        if (check(mid, i - 1)) {
            res = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    return res;
}

int findR(int i) {
    int l = i + 1, r = n, res = i;
    while (l <= r) {
        int mid = l + r >> 1;
        if (check(i + 1, mid)) {
            res = mid;
            l = mid + 1;
        } else {
            r = mid - 1;
        }
    }
    return res;
}

void flip(int i, int cur, bool prep) {
    int L = findL(i);
    int R = findR(i);
    if (s[i] == '1') {
        del(L, R, cur, prep);
        add(L, i - 1, cur);
        add(i + 1, R, cur);
        ft::upd(i, -1);
        s[i] = '0';
    } else {
        add(L, R, cur);
        del(L, i - 1, cur, prep);
        del(i + 1, R, cur, prep);
        ft::upd(i, 1);
        s[i] = '1';
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    #ifdef ngu
    freopen("test.inp", "r", stdin);
    freopen("test.out", "w", stdout);
    #endif
    cin >> n >> q >> s;
    s = '&' + s;
    for (int i = 1; i <= n; ++i) {
        if (s[i] == '1') {
            ft::upd(i, 1);
        }
    }
    for (int i = 1; i <= n; ++i) {
        if (s[i] == '1') {
            int j = i;
            while (j <= n && s[j] == '1') {
                j++;
            }
            m[{i, j - 1}] = 0;
            i = j - 1;
        }
    }
    for (int i = 1; i <= q; ++i) {
        string type;
        cin >> type;
        t[i] = type[0] == 'q' ? 0 : 1;
        if (t[i] == 0) {
            cin >> l[i] >> r[i];
            fake_get(l[i], r[i] - 1);
        } else {
            int j;
            cin >> j;
            p[i] = j;
            flip(j, i, true);
        }
    }
    for (int i = 1; i <= n; ++i) {
        sort(tree[i].begin(), tree[i].end());
        tree[i].erase(unique(tree[i].begin(), tree[i].end()), tree[i].end());
        f[i].resize((int) tree[i].size() + 1);
    }
    ft::reset();
    for (int i = q; i >= 1; --i) {
        if (t[i]) {
            int j = p[i];
            s[j] = s[j] == '0' ? '1' : '0';
        }
    }
    for (int i = 1; i <= n; ++i) {
        if (s[i] == '1') {
            ft::upd(i, 1);
        }
    }
    m.clear();
    for (int i = 1; i <= q; ++i) {
        for (auto [l, r, v] : seg[i]) {
            upd(l, r, v);
        }
        if (t[i] == 0) {
            int res = get(l[i], r[i] - 1);
            if (check(l[i], r[i] - 1)) {
                int L = findL(l[i]);
                int R = findR(r[i] - 1);
                res += i - m[{L, R}];
            }
            cout << res << "\n";
        } else {
            int j = p[i];
            flip(j, i, false);
        }
    }
}

컴파일 시 표준 에러 (stderr) 메시지

street_lamps.cpp: In function 'int findL(int)':
street_lamps.cpp:95:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   95 |         int mid = l + r >> 1;
      |                   ~~^~~
street_lamps.cpp: In function 'int findR(int)':
street_lamps.cpp:109:21: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  109 |         int mid = l + r >> 1;
      |                   ~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...