This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#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) {
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) {
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);
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), mp[l + 1] = {r, curtime, iinf};
else if (pos == r) add_seg(curtime, iinf, l, r - 1), mp[l] = {r - 1, curtime, iinf};
else {
add_seg(curtime, iinf, l, pos - 1);
add_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');
};
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]);
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
*/
Compilation message (stderr)
street_lamps.cpp: In function 'void solve()':
street_lamps.cpp:94:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
94 | for (auto &[l, __] : mp) {
| ^
street_lamps.cpp:95:9: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
95 | auto &[r, lt, rt] = __;
| ^
street_lamps.cpp: In lambda function:
street_lamps.cpp:104:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
104 | auto [r, lt, rt] = it->se;
| ^
street_lamps.cpp:114:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
114 | auto [r, lt, rt] = it->se;
| ^
street_lamps.cpp:126:25: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
126 | int l = it->fi; auto [r, lt, rt] = it->se;
| ^
street_lamps.cpp: In lambda function:
street_lamps.cpp:150:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
150 | auto [r, lt, rt] = it->se;
| ^
street_lamps.cpp:161:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
161 | auto [r, lt, rt] = it->se;
| ^
street_lamps.cpp:174:25: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
174 | int l = it->fi; auto [r, lt, rt] = it->se;
| ^
street_lamps.cpp: In function 'void solve()':
street_lamps.cpp:230:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
230 | for (auto &[l, __] : mp) add_seg(0, iinf, l, __[0]);
| ^
street_lamps.cpp:233:13: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
233 | for (auto &[e, l, r] : que) { ++tm;
| ^
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |