Submission #126061

#TimeUsernameProblemLanguageResultExecution timeMemory
126061triStreet Lamps (APIO19_street_lamps)C++14
100 / 100
1704 ms60596 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef pair<int, int> pi; typedef vector<int> vi; typedef vector<ld> vd; typedef vector<ll> vl; #define pb push_back #define f first #define s second namespace debug { const int DEBUG = false; template<class T1, class T2> void pr(const pair<T1, T2> &x); template<class T, size_t SZ> void pr(const array<T, SZ> &x); template<class T> void pr(const vector<T> &x); template<class T> void pr(const set<T> &x); template<class T1, class T2> void pr(const map<T1, T2> &x); template<class T> void pr(const T &x) { if (DEBUG) cout << x; } template<class T, class... Ts> void pr(const T &first, const Ts &... rest) { pr(first), pr(rest...); } template<class T1, class T2> void pr(const pair<T1, T2> &x) { pr("{", x.f, ", ", x.s, "}"); } template<class T> void prIn(const T &x) { pr("{"); bool fst = 1; for (auto &a : x) { pr(fst ? "" : ", ", a), fst = 0; } pr("}"); } template<class T, size_t SZ> void pr(const array<T, SZ> &x) { prIn(x); } template<class T> void pr(const vector<T> &x) { prIn(x); } template<class T> void pr(const set<T> &x) { prIn(x); } template<class T1, class T2> void pr(const map<T1, T2> &x) { prIn(x); } void ps() { pr("\n"); } template<class Arg, class... Args> void ps(const Arg &first, const Args &... rest) { pr(first, " "); ps(rest...); } } using namespace debug; const int INF = 100000000; static int searchF(vi &a, int x) { // returns first element ge x return lower_bound(a.begin(), a.end(), x) - a.begin(); } static int searchL(vi &a, int x) { // returns last element le x return upper_bound(a.begin(), a.end(), x) - a.begin() - 1; } struct BIT2D { // 2D BIT with 0 indexing; range updates, points queries struct node { vi yCoor; vi tr; void in_u(int i, int d) { while (i < tr.size()) { tr[i] += d; i = i | (i + 1); } } int in_q(int i) { // ps("in_q:", i); int s = 0; while (i >= 0) { s += tr[i]; i = (i & (i + 1)) - 1; } return s; } void rU(int l, int r, int d) { l = searchF(yCoor, l); r = searchL(yCoor, r); if (l > r) return; in_u(l, d); in_u(r + 1, -d); } int q(int i) { // ps("inside q:", i); // ps(yCoor); // ps("searchL:", searchL(yCoor, i)); return in_q(searchL(yCoor, i)); } }; vector<node> tr; void init(vector<pi> &pts) { int maxX = 0; for (pi cP: pts) { maxX = max(maxX, cP.f); } tr.resize(maxX + 1); // coordinate compress on x if necessary in future for (pi cP: pts) { int i = cP.f; while (i >= 0) { tr[i].yCoor.pb(cP.s); i = (i & (i + 1)) - 1; } } for (node &cN : tr) { sort(cN.yCoor.begin(), cN.yCoor.end()); cN.yCoor.erase(unique(cN.yCoor.begin(), cN.yCoor.end()), cN.yCoor.end()); cN.tr.resize(cN.yCoor.size(), 0); } } void in_rU(int i, int l, int r, int d) { while (i < tr.size()) { // ps("in_rU i:", i); tr[i].rU(l, r, d); i = i | (i + 1); // ps("in_rU post i:", i); } } int q(int i1, int i2) { // ps("q:", i1, i2); int s = 0; while (i1 >= 0) { // ps("i1:", i1); s += tr[i1].q(i2); // ps("qRes:", tr[i1].q(i2)); i1 = (i1 & (i1 + 1)) - 1; // ps("post i1:", i1); } return s; } void rU(int l1, int r1, int l2, int r2, int d) { if (l1 > r1) return; in_rU(l1, l2, r2, d); in_rU(r1 + 1, l2, r2, -d); } } bit2D; int main() { int N, Q; cin >> N >> Q; string line; cin >> line; vector<bool> state(N); for (int i = 0; i < N; i++) { state[i] = line[i] == '1'; } vector<pi> qs; vector<pi> pts; for (int i = 0; i < Q; i++) { string t; cin >> t; if (t == "toggle") { int x; cin >> x; x--; qs.pb({-1, x}); } else { int l, r; cin >> l >> r; l--, r -= 2; qs.pb({l, r}); pts.pb({l, r}); } } // ps(pts); bit2D.init(pts); // ps(bit2D.tr[0].yCoor); // ps(bit2D.tr[1].yCoor); // ps(bit2D.tr[2].yCoor); // // ps("f2"); // // bit2D.tr[1].rU(2, 4, -5); // ps(bit2D.tr[1].q(3)); // // ps("f3"); // // ps(bit2D.q(2, 3)); // ps("prelim done"); // bit2D.rU(1, 2, 2, 4, -5); // // bit2D.rU(0, 2, 2, 4, -5); // ps("passed in: (2, 3)"); // ps(bit2D.q(2, 3)); set<pi> segs; for (int i = 0; i < N;) { while (!state[i]) { i++; continue; } int j = i; while (j + 1 < N && state[j + 1]) { j++; } segs.insert({i, j}); i = j + 1; } // ps("queries begin"); // ps(segs); for (int cT = 1; cT <= Q; cT++) { pi cQ = qs[cT - 1]; auto aftIt = segs.upper_bound({cQ.s, INF}); if (cQ.f == -1) { // update int x = cQ.s; if (state[x]) { pi cSeg = *(--aftIt); segs.erase(cSeg); if (cSeg.f < x) { segs.insert({cSeg.f, x - 1}); } if (x < cSeg.s) { segs.insert({x + 1, cSeg.s}); } bit2D.rU(cSeg.f, x, x, cSeg.s, cT); } else { int l = x, r = x; if (aftIt != segs.end()) { pi aft = *aftIt; // ps("aft: ", aft); if (x + 1 == aft.f) { segs.erase(aft); r = aft.s; aftIt = segs.upper_bound({x, INF}); } } if (aftIt != segs.begin()) { pi bef = *(--aftIt); // ps("bef:", bef); if (bef.s == x - 1) { segs.erase(bef); l = bef.f; } } segs.insert({l, r}); // ps("l x r", l, x, r); // ps(bit2D.q(2, 3)); bit2D.rU(l, x, x, r, -cT); // ps(bit2D.q(2, 3)); } state[x] = !state[x]; } else { // ps("p query"); // ps(cQ.f, cQ.s); int ans = bit2D.q(cQ.f, cQ.s); // ps("obt ans", ans); if (aftIt != segs.begin()) { pi around = *(--aftIt); // ps("around:", around); // ps(cQ.f, cQ.s); // ps(around.f <= cQ.f); // ps(cQ.s <= around.s); if (around.f <= cQ.f && cQ.s <= around.s) { // interval is still active ans += cT; } } cout << ans << '\n'; } // ps("finished:", cT); // for (int i = 0; i < N; i++) { // pr(state[i]); // } // ps(); // ps("relevant:", bit2D.q(0, 2)); // ps(segs); } cout << flush; }

Compilation message (stderr)

street_lamps.cpp: In member function 'void BIT2D::node::in_u(int, int)':
street_lamps.cpp:94:22: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
             while (i < tr.size()) {
                    ~~^~~~~~~~~~~
street_lamps.cpp: In member function 'void BIT2D::in_rU(int, int, int, int)':
street_lamps.cpp:152:18: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         while (i < tr.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...
#Verdict Execution timeMemoryGrader output
Fetching results...