제출 #556567

#제출 시각아이디문제언어결과실행 시간메모리
556567vovamr가로등 (APIO19_street_lamps)C++17
60 / 100
5063 ms232212 KiB
#include <bits/stdc++.h> #include <ext/pb_ds/assoc_container.hpp> #include <ext/pb_ds/tree_policy.hpp> #define fi first #define se second #define ll long long #define ld long double #define sz(x) ((int)(x).size()) #define all(x) (x).begin(), (x).end() #define pb push_back #define mpp make_pair #define ve vector using namespace std; using namespace __gnu_pbds; template<class T> using oset = tree<T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>; const ll inf = 1e18; const int iinf = 1e9; typedef pair<ll, ll> pll; typedef pair<int, int> pii; mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); template <typename T> inline bool chmin(T& a, T b) { return (a > b ? a = b, 1 : 0); } template <typename T> inline bool chmax(T& a, T b) { return (a < b ? a = b, 1 : 0); } const int N = 3e5 + 100; ve<ve<int>> q[3]; ve<ve<int>> f[3]; int nn; inline void pupd(int id, int x, int y) { x += 2; for (; x < nn; x += x & -x) q[id][x].pb(y); } inline void pget(int id, int x, int y) { x += 2; for (; x; x -= x & -x) q[id][x].pb(y); } inline void psum(int id, int lx, int ry) { pget(id, lx, nn - 5); pget(id, lx, ry - 1); } inline void prep(int id) { for (int i = 0; i < nn; ++i) { sort(all(q[id][i])); q[id][i].erase(unique(all(q[id][i])), q[id][i].end()); f[id][i].resize(sz(q[id][i]) + 10); } } inline void upd(int id, int x, int y, int d) { x += 2; for (; x < nn; x += x & -x) { int i = lower_bound(all(q[id][x]), y) - q[id][x].begin() + 2; for (; i < sz(f[id][x]); i += i & -i) f[id][x][i] += d; } } inline int get(int id, int x, int y) { if (y < 0) return 0; x += 2; int ans = 0; for (; x; x -= x & -x) { int i = lower_bound(all(q[id][x]), y) - q[id][x].begin() + 2; for (; i; i -= i & -i) ans += f[id][x][i]; } return ans; } inline int sum(int id, int lx, int ry) { return get(id, lx, nn - 5) - get(id, lx, ry - 1); } inline void begin(int n) { nn = n + 10; for (int i : {0, 1, 2}) { f[i].resize(nn); q[i].resize(nn); } } inline void solve() { int n, q; cin >> n >> q; string s; cin >> s; begin(n); string ini = s; map<int,array<int,3>> mp; int ls = -1; for (int i = n - 1; ~i; --i) { if (s[i] == '1' && ls == -1) ls = i; else if (s[i] == '0') { if (i + 1 < n && s[i + 1] == '1') { mp[i + 1] = {ls, 0, iinf}; } ls = -1; } } if (s[0] == '1') mp[0] = {ls, 0, iinf}; auto Padd_seg = [&](int lt, int rt, int l, int r) { pupd(0, l, r); if (rt == iinf) pupd(1, l, r); else pupd(2, l, r); }; auto add_seg = [&](int lt, int rt, int l, int r, bool fl = 0) { if (fl) upd(0, l, r, -lt); if (rt == iinf) upd(1, l, r, +1); else upd(2, l, r, +(rt + 1)); }; auto del_seg = [&](int lt, int rt, int l, int r, bool fl = 0) { if (fl) upd(0, l, r, +lt); if (rt == iinf) upd(1, l, r, -1); else upd(2, l, r, -(rt + 1)); }; for (auto &[l, __] : mp) { auto &[r, lt, rt] = __; Padd_seg(lt, rt, l, r); } auto Pupd = [&](int pos, int curtime) { if (s[pos] == '0') { pii add = {pos, pos}; auto it = mp.upper_bound(pos); if (it != mp.end()) { auto [r, lt, rt] = it->se; if (it->fi == pos + 1) { add = {add.fi, r}; Padd_seg(lt, curtime - 1, it->fi, r); mp.erase(it); } } it = mp.upper_bound(pos); if (it != mp.begin()) { --it; auto [r, lt, rt] = it->se; if (r == pos - 1) { add = {it->fi, add.se}; Padd_seg(lt, curtime - 1, it->fi, r); mp.erase(it); } } Padd_seg(curtime, iinf, add.fi, add.se); mp[add.fi] = {add.se, curtime, iinf}; } else { auto it = mp.upper_bound(pos); --it; int l = it->fi; auto [r, lt, rt] = it->se; Padd_seg(lt, curtime - 1, l, r); mp.erase(it); if (l != r) { if (pos == l) Padd_seg(curtime, iinf, l + 1, r), mp[l + 1] = {r, curtime, iinf}; else if (pos == r) Padd_seg(curtime, iinf, l, r - 1), mp[l] = {r - 1, curtime, iinf}; else { Padd_seg(curtime, iinf, l, pos - 1); Padd_seg(curtime, iinf, pos + 1, r); mp[l] = {pos - 1, curtime, iinf}; mp[pos + 1] = {r, curtime, iinf}; } } } s[pos] = (s[pos] == '0' ? '1' : '0'); }; auto upd = [&](int pos, int curtime) { if (s[pos] == '0') { pii add = {pos, pos}; auto it = mp.upper_bound(pos); if (it != mp.end()) { auto [r, lt, rt] = it->se; if (it->fi == pos + 1) { add = {add.fi, r}; del_seg(lt, rt, it->fi, r); add_seg(lt, curtime - 1, it->fi, r); mp.erase(it); } } it = mp.upper_bound(pos); if (it != mp.begin()) { --it; auto [r, lt, rt] = it->se; if (r == pos - 1) { add = {it->fi, add.se}; del_seg(lt, rt, it->fi, r); add_seg(lt, curtime - 1, it->fi, r); mp.erase(it); } } add_seg(curtime, iinf, add.fi, add.se, 1); mp[add.fi] = {add.se, curtime, iinf}; } else { auto it = mp.upper_bound(pos); --it; int l = it->fi; auto [r, lt, rt] = it->se; del_seg(lt, rt, l, r); add_seg(lt, curtime - 1, l, r); mp.erase(it); if (l != r) { if (pos == l) add_seg(curtime, iinf, l + 1, r, 1), mp[l + 1] = {r, curtime, iinf}; else if (pos == r) add_seg(curtime, iinf, l, r - 1, 1), mp[l] = {r - 1, curtime, iinf}; else { add_seg(curtime, iinf, l, pos - 1, 1); add_seg(curtime, iinf, pos + 1, r, 1); mp[l] = {pos - 1, curtime, iinf}; mp[pos + 1] = {r, curtime, iinf}; } } } s[pos] = (s[pos] == '0' ? '1' : '0'); }; int ttm = 0; ve<array<int,3>> que(q); for (int i = 0; i < q; ++i) { ttm++; string e; cin >> e; que[i][0] = (e == "toggle" ? 0 : 1); if (e == "toggle") { int pos; cin >> pos, --pos; Pupd(pos, ttm++); que[i][1] = pos; que[i][2] = -1; } else { int l, r; cin >> l >> r, --l, ----r; que[i][1] = l, que[i][2] = r; psum(0, l, r); psum(1, l, r); psum(2, l, r); } } prep(0), prep(1), prep(2); s = ini; mp.clear(); ls = -1; for (int i = n - 1; ~i; --i) { if (s[i] == '1' && ls == -1) ls = i; else if (s[i] == '0') { if (i + 1 < n && s[i + 1] == '1') { mp[i + 1] = {ls, 0, iinf}; } ls = -1; } } if (s[0] == '1') mp[0] = {ls, 0, iinf}; for (auto &[l, __] : mp) add_seg(0, iinf, l, __[0], 1); int tm = 0; for (auto &[e, l, r] : que) { ++tm; if (!e) upd(l, tm); else { int ans = 0; ans += sum(2, l, r); ans += sum(0, l, r); ans += tm * sum(1, l, r); cout << ans << '\n'; } } } signed main() { ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0); int q = 1; // cin >> q; while (q--) solve(); cerr << fixed << setprecision(3) << "Time execution: " << (double)clock() / CLOCKS_PER_SEC << endl; } /** 5 7 11011 query 1 2 query 1 2 query 1 6 query 3 4 toggle 3 query 3 5 query 1 6 */
#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...