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>
using namespace std;
using namespace __gnu_pbds;
#define endl '\n'
#define fi first
#define se second
#define For(i, l, r) for (auto i = (l); i < (r); i++)
#define ForE(i, l, r) for (auto i = (l); i <= (r); i++)
#define FordE(i, l, r) for (auto i = (l); i >= (r); i--)
#define Fora(v, a) for (auto v: (a))
#define bend(a) (a).begin(), (a).end()
#define isz(a) ((signed)(a).size())
using ll = long long;
using ld = long double;
using pii = pair <int, int>;
using vi = vector <int>;
using vpii = vector <pii>;
using vvi = vector <vi>;
template<class T, class F>
struct segment_tree{
int n, size, log;
vector<T> data;
F TT; // monoid operation (always adjacent)
T T_id; // monoid identity
// O(n)
segment_tree(int n, F TT, T T_id): segment_tree(vector<T>(n, T_id), TT, T_id){}
// O(n)
segment_tree(int n, T init, F TT, T T_id): segment_tree(vector<T>(n, init), TT, T_id){}
// O(n)
segment_tree(const vector<T> &a, F TT, T T_id): n((int)a.size()), TT(TT), T_id(T_id){ // O(n)
log = __lg(max(n - 1, 1)) + 1, size = 1 << log;
data = vector<T>(size << 1, T_id);
copy(a.begin(), a.end(), data.begin() + size);
for(auto i = size - 1; i >= 1; -- i) refresh(i);
}
// O(1)
void refresh(int i){
data[i] = TT(data[i << 1], data[i << 1 | 1]);
}
// O(log n)
void set(int p, T x){
assert(0 <= p && p < n);
data[p += size] = x;
for(auto i = 1; i <= log; ++ i) refresh(p >> i);
}
// O(log n)
void update(int p, T x){
assert(0 <= p && p < n);
p += size;
data[p] = TT(data[p], x);
for(auto i = 1; i <= log; ++ i) refresh(p >> i);
}
// O(1)
T query(int p) const{
assert(0 <= p && p < n);
return data[p + size];
}
// O(log n)
T query(int l, int r) const{
assert(0 <= l && l <= r && r <= n);
T res_left = T_id, res_right = T_id;
for(l += size, r += size; l < r; l >>= 1, r >>= 1){
if(l & 1) res_left = TT(res_left, data[l ++]);
if(r & 1) res_right = TT(data[-- r], res_right);
}
return TT(res_left, res_right);
}
// O(1)
T query_all() const{
return data[1];
}
// pred(sum[l, r)) is T, T, ..., T, F, F, ..., F
// Returns max r with T
// O(log n)
int max_pref(int l, auto pred) const{
assert(0 <= l && l <= n && pred(T_id));
if(l == n) return n;
l += size;
T sm = T_id;
do{
while(~l & 1) l >>= 1;
if(!pred(TT(sm, data[l]))){
while(l < size){
l = l << 1;
if(pred(TT(sm, data[l]))) sm = TT(sm, data[l ++]);
}
return l - size;
}
sm = TT(sm, data[l ++]);
}while((l & -l) != l);
return n;
}
// pred(sum[l, r)) is F, F, ..., F, T, T, ..., T
// Returns min l with T
// O(log n)
int min_suff(int r, auto pred) const{
assert(0 <= r && r <= n && pred(T_id));
if(r == 0) return 0;
r += size;
T sm = T_id;
do{
-- r;
while(r > 1 && r & 1) r >>= 1;
if(!pred(TT(data[r], sm))){
while(r < size){
r = r << 1 | 1;
if(pred(TT(data[r], sm))) sm = TT(data[r --], sm);
}
return r + 1 - size;
}
sm = TT(data[r], sm);
}while((r & -r) != r);
return 0;
}
template<class output_stream>
friend output_stream &operator<<(output_stream &out, const segment_tree<T, F> &seg){
out << "[";
for(auto i = 0; i < seg.n; ++ i){
out << seg.query(i);
if(i != seg.n - 1) out << ", ";
}
return out << ']';
}
};
const int N = 5e5 + 5;
struct node_t{
int sum, minsuf;
node_t(int x = 0){
sum = x;
minsuf = min(0, x);
}
};
auto merge_node_t = [](const node_t &lhs, const node_t &rhs){
node_t ans;
ans.sum = lhs.sum + rhs.sum;
ans.minsuf = min(lhs.minsuf + rhs.sum, rhs.minsuf);
return ans;
};
segment_tree seg(N, merge_node_t, node_t());
int n;
int a[N];
int q;
pii b[N];
vi vidxb[N];
int ans[N];
signed main(){
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
// freopen("KEK.inp", "r", stdin);
// freopen("KEK.out", "w", stdout);
cin >> n;
ForE(i, 1, n){
char c; cin >> c;
a[i] = (c == 'C' ? 1 : -1);
}
cin >> q;
ForE(i, 1, q){
cin >> b[i].fi >> b[i].se;
}
ForE(i, 1, q){
vidxb[b[i].fi].emplace_back(i);
}
vi st;
FordE(i, n, 1){
if (a[i] < 0){
st.emplace_back(i);
}
else{
if (!st.empty()){
int j = st.back(); st.pop_back();
seg.set(j, node_t(-1));
}
seg.set(i, node_t(1));
}
Fora(ib, vidxb[i]){
int j = b[ib].se;
node_t cac = seg.query(i, j + 1);
int cnt = isz(st) - (lower_bound(bend(st), j, [&](int lhs, int rhs){
return lhs > rhs;
}) - st.begin());
ans[ib] = -cac.minsuf + cnt;
}
}
ForE(i, 1, q){
cout << ans[i] << endl;
}
}
/*
==================================================+
INPUT: |
--------------------------------------------------|
--------------------------------------------------|
==================================================+
OUTPUT: |
--------------------------------------------------|
--------------------------------------------------|
==================================================+
*/
Compilation message (stderr)
election.cpp:80:22: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
80 | int max_pref(int l, auto pred) const{
| ^~~~
election.cpp:101:22: warning: use of 'auto' in parameter declaration only available with '-fconcepts-ts'
101 | int min_suff(int r, auto pred) const{
| ^~~~
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |