Submission #122519

#TimeUsernameProblemLanguageResultExecution timeMemory
122519abacabaStreet Lamps (APIO19_street_lamps)C++14
100 / 100
1721 ms200512 KiB
#include <bits/stdc++.h>
using namespace std;

const int N = 3e5 + 15;
int n, q, fenw[N], a[N];

struct node {
	node *l, *r;
	int val, add, pr, key;
	node() : val(0), add(0), pr(0), l(NULL), r(NULL) {}
	node(int key) : key(key), val(0), add(0), pr(0), l(NULL), r(NULL) {
		pr = (int)rand() * rand();
	}
};

struct query {
	int type, l, r;
} qs[N];

struct upd {
	int l, r, val;
	upd(int l, int r, int val) : l(l), r(r), val(val) {}
};

typedef node* pnode;

void push(pnode &t) {
	if(t) {
		if(t->l) {
			t->l->add += t->add;
			t->l->val += t->add;
		}
		if(t->r) {
			t->r->add += t->add;
			t->r->val += t->add;
		}
		t->add = 0;
	}
}

void split(pnode t, pnode &l, pnode &r, int key) {
	if(!t)
		return void(l = r = t);
	push(t);
	if(t->key <= key)
		split(t->r, t->r, r, key), l = t;
	else
		split(t->l, l, t->l, key), r = t;
}

void merge(pnode &t, pnode l, pnode r) {
	push(l);
	push(r);
	if(!l || !r)
		t = l ? l : r;
	else if(l->pr > r->pr)
		merge(l->r, l->r, r), t = l;
	else
		merge(r->l, l, r->l), t = r;
}

inline void inc(int i, int val) {
	for(; i <= n; i = (i | (i + 1)))
		fenw[i] += val;
}

inline int get(int i) {
	int res = 0;
	for(; i >= 1; i = (i & (i + 1)) - 1)
		res += fenw[i];
	return res;
}

inline int get(int l, int r) {
	if(l > r)
		return 0;
	return get(r) - get(l - 1);
}

void change(int i) {
	inc(i, -a[i]);
	a[i] ^= 1;
	inc(i, a[i]);
}

pnode t[N << 4];
vector <upd> add[N << 4];

int getleft(int j) {
	int l = 1, r = j, leftmost = j;
	while(l <= r) {
		int mid = l + r >> 1;
		if(j - mid == get(mid, j - 1)) {
			leftmost = mid;
			r = mid - 1;
		}
		else
			l = mid + 1;
	}
	return leftmost;
}

int getright(int j) {
	int l = j, r = n, rightmost = j;
	while(l <= r) {
		int mid = l + r >> 1;
		if(mid - j == get(j + 1, mid)) {
			rightmost = mid;
			l = mid + 1;
		}
		else
			r = mid - 1;
	}
	return rightmost;
}

void update(int v, int mostleft, int mostright, int val) {
	pnode t1, t23, t2, t3, cur;
	cur = t[v];
	split(cur, t1, t23, mostleft - 1);
	split(t23, t2, t3, mostright);
	if(t2) {
		t2->add += val;
		t2->val += val;
	}
	merge(t23, t2, t3);
	merge(cur, t1, t23);
}

void pusht(int v) {
	while(!add[v].empty()) {
		upd now = add[v].back();
		add[v << 1].push_back(now);
		add[v << 1 | 1].push_back(now);
		add[v].pop_back();
		update(v << 1, now.l, now.r, now.val);
		update(v << 1 | 1, now.l, now.r, now.val);
	}
}

void multiupdate(int v, int tl, int tr, int l, int r, int mostleft, int mostright, int val) {
	if(tl > r || tr < l || l > r)
		return;
	pusht(v);
	if(tl >= l && tr <= r) {
		add[v].push_back(*new upd(mostleft, mostright, val));
		update(v, mostleft, mostright, val);
		return;
	}
	int mid = tl + tr >> 1;
	multiupdate(v << 1, tl, mid, l, r, mostleft, mostright, val);
	multiupdate(v << 1 | 1, mid + 1, tr, l, r, mostleft, mostright, val);
}

void update(int v, int tl, int tr, int pos, pnode val) {
	if(tl == tr) {
		t[v] = val;
		return;
	}
	int mid = tl + tr >> 1;
	if(pos <= mid)
		update(v << 1, tl, mid, pos, val);
	else
		update(v << 1 | 1, mid + 1, tr, pos, val);
}

int get(int v, int tl, int tr, int l, int r) {
	pusht(v);
	if(tl == tr) {
		pnode t1, t23, t2, t3;
		split(t[v], t1, t23, l - 1);
		split(t23, t2, t3, l);
		int ans = 0;
		if(t2)
			ans = t2->val;
		merge(t23, t2, t3);
		merge(t[v], t1, t23);
		return ans;
	}
	int mid = tl + tr >> 1;
	if(r <= mid)
		return get(v << 1, tl, mid, l, r);
	return get(v << 1 | 1, mid + 1, tr, l, r);
}

set <int> rs[N], temporaryR;

int main() {
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> n >> q;
	for(int i = 1; i <= n; ++i) {
		char c;
		cin >> c;
		a[i] = (c == '1');
		inc(i, a[i]);
	}
	for(int i = 1; i <= q; ++i) {
		string s;
		cin >> s;
		qs[i].type = (s[0] != 't') + 1;
		if(qs[i].type == 1) {
			int j;
			cin >> j;
			qs[i].l = j;
		}
		else {
			cin >> qs[i].l >> qs[i].r;
			--qs[i].r;
			rs[qs[i].r].insert(qs[i].l);
			temporaryR.insert(qs[i].r);
		}
	}
	for(set <int>::iterator it = temporaryR.begin(); it != temporaryR.end(); ++it) {
		int r = *it;
		pnode t = NULL;
		for(set <int>::iterator ik = rs[r].begin(); ik != rs[r].end(); ++ik)
			merge(t, t, new node(*ik));
		update(1, 1, n, r, t);
	}
	for(int i = 1; i <= q; ++i) {
		if(qs[i].type == 1) {
			int j = qs[i].l;
			change(j);
			int leftmost = getleft(j);
			int rightmost = getright(j);
			if(!a[j])
				multiupdate(1, 1, n, j, rightmost, leftmost, j, i);
			else
				multiupdate(1, 1, n, j, rightmost, leftmost, j, -i);
		}
		else {
			int val = get(qs[i].l, qs[i].r);
			int ans = get(1, 1, n, qs[i].l, qs[i].r);
			if(val == qs[i].r - qs[i].l + 1)
				ans += i;
			cout << ans << endl;
		}
	}
	return 0;
}

Compilation message (stderr)

street_lamps.cpp: In constructor 'node::node()':
street_lamps.cpp:9:16: warning: 'node::pr' will be initialized after [-Wreorder]
  int val, add, pr, key;
                ^~
street_lamps.cpp:8:8: warning:   'node* node::l' [-Wreorder]
  node *l, *r;
        ^
street_lamps.cpp:10:2: warning:   when initialized here [-Wreorder]
  node() : val(0), add(0), pr(0), l(NULL), r(NULL) {}
  ^~~~
street_lamps.cpp: In constructor 'node::node(int)':
street_lamps.cpp:9:20: warning: 'node::key' will be initialized after [-Wreorder]
  int val, add, pr, key;
                    ^~~
street_lamps.cpp:9:6: warning:   'int node::val' [-Wreorder]
  int val, add, pr, key;
      ^~~
street_lamps.cpp:11:2: warning:   when initialized here [-Wreorder]
  node(int key) : key(key), val(0), add(0), pr(0), l(NULL), r(NULL) {
  ^~~~
street_lamps.cpp:9:16: warning: 'node::pr' will be initialized after [-Wreorder]
  int val, add, pr, key;
                ^~
street_lamps.cpp:8:8: warning:   'node* node::l' [-Wreorder]
  node *l, *r;
        ^
street_lamps.cpp:11:2: warning:   when initialized here [-Wreorder]
  node(int key) : key(key), val(0), add(0), pr(0), l(NULL), r(NULL) {
  ^~~~
street_lamps.cpp: In function 'int getleft(int)':
street_lamps.cpp:92:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid = l + r >> 1;
             ~~^~~
street_lamps.cpp: In function 'int getright(int)':
street_lamps.cpp:106:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
   int mid = l + r >> 1;
             ~~^~~
street_lamps.cpp: In function 'void multiupdate(int, int, int, int, int, int, int, int)':
street_lamps.cpp:150:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = tl + tr >> 1;
            ~~~^~~~
street_lamps.cpp: In function 'void update(int, int, int, int, pnode)':
street_lamps.cpp:160:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = tl + tr >> 1;
            ~~~^~~~
street_lamps.cpp: In function 'int get(int, int, int, int, int)':
street_lamps.cpp:180:15: warning: suggest parentheses around '+' inside '>>' [-Wparentheses]
  int mid = tl + tr >> 1;
            ~~~^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...