제출 #1129789

#제출 시각아이디문제언어결과실행 시간메모리
1129789rxlfd314가로등 (APIO19_street_lamps)C++17
100 / 100
3258 ms26328 KiB
#include <bits/stdc++.h> using namespace std; using ari2 = array<int, 2>; using ari3 = array<int, 3>; template <class T> using vt = vector<T>; #define size(x) (int((x).size())) #define all(x) begin(x), end(x) #define REP(a,b,c,d) for(int a=(b);(d)>0?a<=(c):a>=(c);a+=(d)) #define FOR(a,b,c) REP(a,b,c,1) #define ROF(a,b,c) REP(a,b,c,-1) constexpr int mxN = 300005; int N, Q, queries[mxN][3]; bool lamp[mxN]; struct BIT { int fen[mxN]; void update(int i, int v) { for (++i; i <= N; i += i & -i) fen[i] += v; } int query(int i) { int ret = 0; for (++i; i > 0; i -= i & -i) ret += fen[i]; return ret; } int query(int l, int r) { return query(r) - query(l-1); } } fen; multiset<ari3> ranges; int ans[mxN]; void dnc(const int tl, const int tr) { const int tm = tl + tr >> 1; vt<ari3> events, rescind, restore; FOR(i, tm+(tl<tr), tr) if (queries[i][0] == 1) events.push_back({queries[i][1], queries[i][2], -i - 1}); vt<ari2> lamps; FOR(x, tl, tm) { if (queries[x][0] == 1) continue; const int i = queries[x][1]; if (lamp[i]) { lamps.push_back({i, 1}); lamp[i] = 0; auto it = prev(ranges.lower_bound({i+1, -1, -1})); const auto [l, r, y] = *it; events.push_back({l, r, x - max(y, tl-1)}); if (y < tl) restore.push_back({l, r, y}); ranges.erase(it); if (l < i) { ranges.insert({l, i-1, x}); rescind.push_back({l, i-1, x}); } if (r > i) { ranges.insert({i+1, r, x}); rescind.push_back({i+1, r, x}); } } else { lamps.push_back({i, 0}); lamp[i] = 1; ari3 ins = {i, i, x}; { auto it = ranges.lower_bound({i, -1, -1}); if (it == ranges.end()) goto jail; const auto [l, r, y] = *it; if (l == i + 1) { events.push_back({l, r, x - max(y, tl-1)}); ranges.erase(it); ins[1] = r; if (y < tl) restore.push_back({l, r, y}); } } jail:; { auto it = ranges.lower_bound({i, -1, -1}); if (it == ranges.begin()) goto the_asd_clinic; it--; const auto [l, r, y] = *it; if (r == i - 1) { events.push_back({l, r, x - max(y, tl-1)}); ranges.erase(it); ins[0] = l; if (y < tl) restore.push_back({l, r, y}); } } the_asd_clinic:; ranges.insert(ins); rescind.push_back(ins); } } #ifdef DEBUG cout << "new ranges " << tl << ' ' << tr << ":\n"; for (auto [l, r, _] : ranges) cout << l << ' ' << r << '\n'; #endif sort(all(events), [&](const ari3 &a, const ari3 &b) { if (a[0] != b[0]) return a[0] < b[0]; return a[2] > b[2]; }); for (auto [l, r, v] : events) { if (v < 0) { v = -v - 1; ans[v] += fen.query(r, N-1); auto it = ranges.lower_bound({r+1, -1, -1}); if (it == begin(ranges)) continue; const auto [a, b, t] = *prev(it); if (a <= l && r <= b) ans[v] += tm - max(t, tl-1); #ifdef DEBUG cout << "query " << tl << ' ' << tr << ": " << l << ' ' << r << ' ' << v << '\n'; #endif } else { fen.update(r, v); #ifdef DEBUG cout << "watesiggma " << tl << ' ' << tr << ": " << l << ' ' << r << ' ' << v << '\n'; #endif } } for (auto [l, r, v] : events) if (v >= 0) fen.update(r, -v); if (tl < tr) dnc(tm+1, tr); for (auto &i : rescind) if (ranges.find(i) != ranges.end()) ranges.erase(ranges.find(i)); for (auto &i : restore) ranges.insert(i); reverse(all(lamps)); for (auto &[a, b] : lamps) lamp[a] = b; #ifdef DEBUG cout << "fixed ranges 1: " << tl << ' ' << tr << ":\n"; for (auto [l, r, _] : ranges) cout << l << ' ' << r << '\n'; #endif if (tl < tr) dnc(tl, tm); } signed main() { #ifndef DEBUG ios_base::sync_with_stdio(false); cin.tie(nullptr); #endif cin >> N >> Q; FOR(i, 0, N-1) { char c; cin >> c; lamp[i] = c - '0'; } FOR(i, 0, Q-1) { string qt; cin >> qt >> queries[i][1], queries[i][1]--; if (qt == "query") { queries[i][0] = 1; cin >> queries[i][2], queries[i][2] -= 2; } } int L = N; FOR(i, 0, N-1) { if (lamp[i]) { L = min(L, i); } else { if (L < i) ranges.insert({L, i-1, -1}); L = N; } } if (L < N) ranges.insert({L, N-1, -1}); #ifdef DEBUG cout << "ranges:\n"; for (auto [l, r, _] : ranges) cout << l << ' ' << r << '\n'; #endif dnc(0, Q-1); FOR(i, 0, Q-1) if (queries[i][0] == 1) cout << ans[i] << '\n'; }
#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...