이 제출은 이전 버전의 oj.uz에서 채점하였습니다. 현재는 제출 당시와는 다른 서버에서 채점을 하기 때문에, 다시 제출하면 결과가 달라질 수도 있습니다.
#include "bits/stdc++.h"
using namespace std;
#define int long long
#define ar array
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
struct node{
int y, val, sz, c, sum;
node *lx, *rx;
node(int x, int v) : val(x), sz(1), c(v), sum(v), lx(NULL), rx(NULL){
y = uniform_int_distribution<int>(0, 2e9)(rng);
}
};
struct rbst{
void rec(node* a){
a->sum = (a->lx != NULL ? a->lx->sum : 0) + (a->rx != NULL ? a->rx->sum : 0) + a->c;
}
node* merge(node* a, node* b){
if(a == NULL) return b;
if(b == NULL) return a;
if(a->y > b->y){
a->rx = merge(a->rx, b);
rec(a);
return a;
} else {
b->lx = merge(a, b->lx);
rec(b);
return b;
}
}
ar<node*, 2> split(node* a, int v){
if(a == NULL) return {NULL, NULL};
if(a->val < v){
auto t = split(a->rx, v);
a->rx = t[0]; rec(a);
return {a, t[1]};
} else {
auto t = split(a->lx, v);
a->lx = t[1]; rec(a);
return {t[0], a};
}
}
bool is(node*&a, int x){
if(a == NULL) return false;
if(a->val == x) return true;
if(a->val < x) return is(a->rx, x);
else return is(a->lx, x);
}
void add(node*&root, int x, int v){
if(is(root, x)) return;
node* tmp = new node(x, v);
auto tt = split(root, x);
root = merge(tt[0], tmp);
root = merge(root, tt[1]);
}
int get(node*&a, int x){
if(a == NULL) return 0;
if(a->val <= x){
return (a->lx != NULL ? a->lx->sum : 0) + a->c + get(a->rx, x);
} else {
return get(a->lx, x);
}
}
void print(node* a){
if(a == NULL) return;
print(a->lx);
cout<<a->val<<" ";
print(a->rx);
}
}T;
const int N = 3e5 + 5;
struct ST{
node* tree[N << 2];
void add(int l, int r, int L, int R, int v, int lx = 0, int rx = N, int x = 1){
if(lx > r || rx < l) return;
if(lx >= l && rx <= r){
T.add(tree[x], L, v), T.add(tree[x], R, -v);
return;
} int m = (lx + rx) >> 1;
add(l, r, L, R, v, lx, m, x<<1), add(l, r, L, R, v, m+1, rx, x<<1|1);
}
int get(int l, int r, int lx = 0, int rx = N, int x = 1){
//~ cout<<"->"<<T.get(tree[x], r)[0]<<" "<<T.get(tree[x], r)[1]<<"\n";
if(lx == rx) return T.get(tree[x], r);
int m = (lx + rx) >> 1;
if(l <= m) return T.get(tree[x], r) + get(l, r, lx, m, x<<1);
else return T.get(tree[x], r) + get(l, r, m+1, rx, x<<1|1);
}
}tree;
signed main(){
ios::sync_with_stdio(0); cin.tie(0);
int n, q; cin>>n>>q;
string s; cin>>s;
set<int> ss; ss.insert(-1), ss.insert(n);
for(int i=0;i<n;){
if(s[i] == '0') { ss.insert(i++); continue; }
int j = i;
while(j<n && s[j] == '1') j++;
int l = i;
while(i<j){
//~ cout<<l<<" "<<i<<" ";
//~ cout<<i<<" "<<j<<"\n";
tree.add(l, i, i, j, 1);
i++;
}
}
for(int t=0;t<q;t++){
string q; cin>>q;
if(q == "query"){
int l, r; cin>>l>>r; l--, r-=2;
bool is = 0;
{
auto it = ss.lower_bound(l);
if(r < *it) is = 1;
}
cout<<tree.get(l, r) + is * t<<"\n";
} else {
int p; cin>>p; p--;
if(s[p] == '1'){
auto lx = --ss.upper_bound(p);
auto rx = ss.lower_bound(p);
//~ (*lx) + 1, (*rx) - 1
tree.add(*lx + 1, p, p, *rx, t);
ss.insert(p); s[p] = '0';
} else {
ss.erase(p);
auto lx = --ss.upper_bound(p);
auto rx = ss.lower_bound(p);
tree.add(*lx + 1, p, p, *rx, -t);
s[p] = '1';
}
}
}
}
# | 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... |