This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
//Make CSP great again
//Vengeance
#include <bits/stdc++.h>
#define TASK "TESTCODE"
#define Log2(x) 31 - __builtin_clz(x)
using namespace std;
const int N = 3e5 + 5;
set<pair<int, int> > pivot, dp[N + 1];
vector<int> query[N + 1];
map<int, int> res[N + 1];
int n, q, t[N + 1], a[N + 1], b[N + 1];
string s;
set<pair<int, int> > :: iterator Range(int i)
{
auto it = pivot.upper_bound({i, N});
--it;
return it;
}
struct IT
{
int Tree[4 * N + 1];
int combine(int u, int v)
{
if (min(u, v) == 0)
{
return max(u, v);
}
if (query[u].back() > query[v].back())
{
return u;
}
return v;
}
void BuildTree(int v, int TreeL, int TreeR)
{
if (TreeL == TreeR)
{
Tree[v] = (query[TreeL].empty() ? 0 : TreeL);
return ;
}
int mid = (TreeL + TreeR)/2;
BuildTree(v * 2, TreeL, mid);
BuildTree(v * 2 + 1, mid + 1, TreeR);
Tree[v] = combine(Tree[2 * v], Tree[2 * v + 1]);
}
void update(int v, int TreeL, int TreeR, int pos)
{
if (TreeL == TreeR)
{
query[pos].pop_back();
if (query[pos].empty())
{
Tree[v] = 0;
}
else
{
Tree[v] = v;
}
return ;
}
int mid = (TreeL + TreeR)/2;
if (pos <= mid)
{
update(v * 2, TreeL, mid, pos);
}
else
{
update(v * 2 + 1, mid + 1, TreeR, pos);
}
Tree[v] = combine(Tree[2 * v], Tree[2 * v + 1]);
}
int get(int v, int TreeL, int TreeR, int L, int R)
{
if (L > R)
{
return 0;
}
if (L == TreeL && R == TreeR)
{
return Tree[v];
}
int mid = (TreeL + TreeR)/2;
return combine(get(v * 2, TreeL, mid, L, min(R, mid)), get(v * 2 + 1, mid + 1, TreeR, max(L, mid + 1), R));
}
} tree;
void read()
{
cin >> n >> q >> s;
s = '?' + s;
for (int i = 1; i <= q; ++ i)
{
string ask;
cin >> ask;
if (ask == "query")
{
cin >> a[i] >> b[i];
t[i] = 0;
query[b[i]].push_back(a[i]);
}
else
{
t[i] = 1;
cin >> a[i];
}
}
}
void solve()
{
for (int i = 1; i <= n + 1; ++ i)
{
sort(query[i].begin(), query[i].end());
query[i].erase(unique(query[i].begin(), query[i].end()), query[i].end());
pivot.insert({i, i});
}
tree.BuildTree(1, 1, n + 1);
for (int i = 1; i <= n; ++ i)
{
if (s[i] == '1')
{
int l = Range(i)->first;
pivot.erase({l, i});
pivot.erase({i + 1, i + 1});
pivot.insert({l, i + 1});
while(!query[i + 1].empty() && query[i + 1].back() >= l)
{
res[i + 1][query[i + 1].back()] = 0;
tree.update(1, 1, n + 1, i + 1);
}
}
}
for (int i = 1; i <= q; ++ i)
{
if (t[i] == 1)
{
if (s[a[i]] == '1')
{
auto it = Range(a[i]);
int l = it->first, r = it->second;
pivot.erase(it);
pivot.insert({l, a[i]});
pivot.insert({a[i] + 1, r});
s[a[i]] = '0';
}
else
{
auto it1 = Range(a[i]), it2 = Range(a[i] + 1);
int l = it1->first, r = it2->second;
while(true)
{
int u = tree.get(1, 1, n + 1, it2->first, it2->second);
if (u < l)
{
break;
}
res[u][query[u].back()] = i;
tree.update(1, 1, n + 1, u);
}
pivot.erase(it1);
pivot.erase(it2);
pivot.insert({l, r});
s[a[i]] = '1';
}
}
else
{
if (res[b[i]].find(a[i]) == res[b[i]].end())
{
cout << 0 << '\n';
}
else
{
cout << i - res[b[i]][a[i]] << '\n';
}
}
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
if (fopen(TASK".INP", "r"))
{
freopen(TASK".INP", "r", stdin);
//freopen(TASK".OUT", "w", stdout);
}
int t = 1;
bool typetest = false;
if (typetest)
{
cin >> t;
}
for (int __ = 1; __ <= t; ++ __)
{
//cout << "Case " << __ << ": ";
read();
solve();
}
}
Compilation message (stderr)
street_lamps.cpp: In function 'int main()':
street_lamps.cpp:183:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
183 | freopen(TASK".INP", "r", stdin);
| ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~
# | 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... |