Submission #706047

#TimeUsernameProblemLanguageResultExecution timeMemory
706047600MihneaStreet Lamps (APIO19_street_lamps)C++17
100 / 100
3342 ms256340 KiB
#include <cmath> #include <functional> #include <fstream> #include <iostream> #include <vector> #include <algorithm> #include <string> #include <set> #include <map> #include <list> #include <time.h> #include <math.h> #include <random> #include <deque> #include <queue> #include <unordered_map> #include <unordered_set> #include <iomanip> #include <cassert> #include <bitset> #include <sstream> #include <chrono> #include <cstring> #include <numeric> using namespace std; typedef long long ll; struct T { int i; int t1; int t2; }; struct Q { int l; int r; int iq; }; struct Segment { int l; int r; int x; }; bool operator < (Segment a, Segment b) { return make_pair(a.l, a.r) < make_pair(b.l, b.r); } struct Update { int x; int y; ll val; }; signed main() { #ifdef ONPC FILE* stream; freopen_s(&stream, "input.txt", "r", stdin); #else ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #endif int n, q; string init_config; cin >> n >> q >> init_config; assert((int)init_config.size() == n); for (auto& ch : init_config) { assert(ch == '0' || ch == '1'); } vector<T> v; vector<int> since(n, 0); string cur_config = init_config; vector<vector<int>> ops(q); vector<int> printsol(q, -1); for (int iq = 0; iq < q; iq++) { string s; cin >> s; assert(s == "query" || s == "toggle"); if (s == "query") { int l, r; cin >> l >> r; l--; r--; r--; assert(0 <= l && l <= r && r < n); ops[iq] = { l, r }; } else { assert(s == "toggle"); int i; cin >> i; i--; assert(0 <= i && i < n); cur_config[i] = '0' ^ '1' ^ cur_config[i]; if (cur_config[i] == '1') { v.push_back({ i, since[i], iq - 1 + 1 }); } else { since[i] = iq + 1; } ops[iq] = { i }; } } for (int i = 0; i < n; i++) { if (cur_config[i] == '0') { v.push_back({ i, since[i], q }); } } vector<Q> qs; for (int iq = 0; iq < q; iq++) { if ((int)ops[iq].size() == 2) { int l = ops[iq][0], r = ops[iq][1]; qs.push_back({ l, r, iq }); } } sort(v.begin(), v.end(), [&](T a, T b) {return a.i > b.i; }); sort(qs.begin(), qs.end(), [&](Q a, Q b) {return a.l > b.l; }); vector<vector<int>> interestingPoints(q + 7); vector<vector<ll>> aib(q + 7); { vector<int> what(q + 1, (int)1e9), coef(q + 1, 0); set<Segment> s; what[0] = -1; coef[0] = q + 1; s.insert({ 0, q, -1 }); int pz = 0; vector<Update> updates; updates.push_back({ 0 + 1, what[0] + 1, coef[0] }); for (auto& itqs : qs) { int l = itqs.l; int sol = 0; while (pz < (int)v.size() && l <= v[pz].i) { int st = v[pz].t1, dr = v[pz].t2; while (1) { auto it = s.lower_bound({ dr + 1, -1, 0 }); if (it == s.begin()) { break; } it--; assert(it->l <= dr); if (it->r < st) { break; } assert(it->l <= dr); assert(st <= it->r); vector<Segment> bg; if (dr + 1 <= it->r) { bg.push_back({ dr + 1, it->r, it->x }); } if (it->l <= st - 1) { bg.push_back({ it->l, st - 1, it->x }); } updates.push_back({ it->l + 1, what[it->l] + 1, -coef[it->l] }); coef[it->l] = 0; s.erase(it); for (auto& gu : bg) { updates.push_back({ gu.l + 1, what[gu.l] + 1, -coef[gu.l] }); what[gu.l] = gu.x; coef[gu.l] = gu.r - gu.l + 1; updates.push_back({ gu.l + 1, what[gu.l] + 1, +coef[gu.l] }); s.insert(gu); } } updates.push_back({ st + 1, what[st] + 1, -coef[st] }); what[st] = pz; coef[st] = dr - st + 1; updates.push_back({ st + 1, what[st] + 1, coef[st] }); s.insert({ st, dr, pz }); pz++; } } for (auto& u : updates) { for (int i = u.x; i < (int)interestingPoints.size(); i += i & (-i)) { interestingPoints[i].push_back(u.y); } } for (int x = 1; x < (int)interestingPoints.size(); x++) { sort(interestingPoints[x].begin(), interestingPoints[x].end()); interestingPoints[x].resize(unique(interestingPoints[x].begin(), interestingPoints[x].end()) - interestingPoints[x].begin()); aib[x].resize((int)interestingPoints[x].size() + 1, 0); } } { auto upd = [&](int x, int y, ll val) { if (val == 0) { return; } for (int i = x; i < (int)interestingPoints.size(); i += i & (-i)) { int go = lower_bound(interestingPoints[i].begin(), interestingPoints[i].end(), y) - interestingPoints[i].begin(); assert(0 <= go && go < (int)interestingPoints[i].size()); assert(interestingPoints[i][go] == y); go++; for (int j = go; j < (int)aib[i].size(); j += j & (-j)) { aib[i][j] += val; } } }; auto get = [&](int x, int y) { ll sol = 0; for (int i = x; i >= 1; i -= i & (-i)) { int cnt = 0, low = 0, high = (int)interestingPoints[i].size() - 1; while (low <= high) { int mid = (low + high) / 2; if (interestingPoints[i][mid] <= y) { cnt = mid + 1; low = mid + 1; } else { high = mid - 1; } } for (int j = cnt; j >= 1; j -= j & (-j)) { sol += aib[i][j]; } } return sol; }; vector<int> what(q + 1, (int)1e9), coef(q + 1, 0); set<Segment> s; what[0] = -1; coef[0] = q + 1; s.insert({ 0, q, -1 }); int pz = 0; upd(0 + 1, what[0] + 1, coef[0]); for (auto& itqs : qs) { int l = itqs.l; int sol = 0; while (pz < (int)v.size() && l <= v[pz].i) { int st = v[pz].t1, dr = v[pz].t2; while (1) { auto it = s.lower_bound({ dr + 1, -1, 0 }); if (it == s.begin()) { break; } it--; assert(it->l <= dr); if (it->r < st) { break; } assert(it->l <= dr); assert(st <= it->r); vector<Segment> bg; if (dr + 1 <= it->r) { bg.push_back({ dr + 1, it->r, it->x }); } if (it->l <= st - 1) { bg.push_back({ it->l, st - 1, it->x }); } upd(it->l + 1, what[it->l] + 1, -coef[it->l]); coef[it->l] = 0; s.erase(it); for (auto& gu : bg) { upd(gu.l + 1, what[gu.l] + 1, -coef[gu.l]); what[gu.l] = gu.x; coef[gu.l] = gu.r - gu.l + 1; upd(gu.l + 1, what[gu.l] + 1, +coef[gu.l]); s.insert(gu); } } upd(st + 1, what[st] + 1, -coef[st]); what[st] = pz; coef[st] = dr - st + 1; upd(st + 1, what[st] + 1, coef[st]); s.insert({ st, dr, pz }); pz++; } int r = itqs.r, iq = itqs.iq;; ///it2.i <= r /// 0 0 0 0 0 1 1 1 1 1 1 int Start = pz, low = 0, high = pz - 1; while (low <= high) { int jo = (low + high) / 2; if (v[jo].i <= r) { Start = jo; high = jo - 1; } else { low = jo + 1; } } auto it = s.lower_bound({ iq + 1, -1, 0 }); assert(it != s.begin()); it--; if (it->x <= Start - 1) { sol += iq - it->l + 1; } if (it != s.begin()) { it--; int ant = it->l; sol += get(ant + 1, Start); } printsol[iq] = sol; } } for (int iq = 0; iq < q; iq++) { if ((int)ops[iq].size() == 2) { cout << printsol[iq] << "\n"; } } return 0; }

Compilation message (stderr)

street_lamps.cpp: In function 'int main()':
street_lamps.cpp:155:8: warning: unused variable 'sol' [-Wunused-variable]
  155 |    int sol = 0;
      |        ^~~
#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...