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 <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);
}
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<int> last(q + 1, -1);
set<Segment> s;
s.insert({ 0, q, -1 });
int pz = 0;
for (auto& itqs : qs)
{
int l = itqs.l;
vector<int> nr(q + 1, 0);
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 });
}
s.erase(it);
for (auto& gu : bg)
{
s.insert(gu);
}
}
s.insert({ st, dr, pz });
for (int j = st; j <= dr; j++)
{
last[j] = 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;
}
}
for (int t = 0; t <= iq; t++)
{
if (last[t] <= Start - 1)
{
sol++;
}
}
printsol[iq] = sol;
int ant = -1, sumdim = 0;
for (auto& it : s)
{
assert(ant < it.l);
assert(it.l <= it.r);
sumdim += it.r - it.l + 1;
ant = it.r;
}
assert(sumdim == q + 1);
}
for (int iq = 0; iq < q; iq++)
{
if ((int)ops[iq].size() == 2)
{
cout << printsol[iq] << "\n";
}
}
return 0;
}
# | 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... |