Submission #294416

# Submission time Handle Problem Language Result Execution time Memory
294416 2020-09-08T22:38:53 Z Plurm Street Lamps (APIO19_street_lamps) C++11
0 / 100
3584 ms 477464 KB
#include <bits/stdc++.h>
using namespace std;
int n;
char state[300005];
set<int> setBlock[300005];
vector<int> vectorBlock[300005];
vector<int> FT[300005];
/**
 * Build the (compressed) fenwick tree
 */
void build(int l, int r){
	for(int i = l; i > 0; i -= i & -i){
		setBlock[i].insert(r);
	}
}
void finalizeBuild(int n){
	for(int i = 1; i <= n; i++){
		setBlock[i].insert(1);
		setBlock[i].insert(n);
		for(int x : setBlock[i]){
			vectorBlock[i].push_back(x);
			FT[i].push_back(0);
		}
		FT[i].push_back(0);
	}
}
void add(int l, int r, int x){
	for(int i = l; i <= n; i += i & -i){
		int st = lower_bound(vectorBlock[i].begin(), vectorBlock[i].end(), r) - vectorBlock[i].begin() + 1;
		for(int j = st; j <= vectorBlock[i].size(); j += j & -j){
			FT[i][j] += x;
		}
	}
}
int sum(int l, int r){
	int ret = 0;
	for(int i = l; i > 0; i -= i & -i){
		int st = lower_bound(vectorBlock[i].begin(), vectorBlock[i].end(), r) - vectorBlock[i].begin() + 1;
		assert(vectorBlock[i][st-1] == r);
		for(int j = st; j > 0; j -= j & -j){
			ret += FT[i][j];
		}
	}
	return ret;
}
vector<tuple<char,int,int> > queries;

// Helpers
int seg[1048576];
int lb[1048576];
int rb[1048576];
void hBuild(int c, int l, int r){
	lb[c] = l;
	rb[c] = r;
	seg[c] = -1;
	if(l == r) return;
	int k = (l+r)/2;
	hBuild(2*c, l, k);
	hBuild(2*c+1, k+1, r);
}
void hUpdate(int c, int l, int r, int x){
	if(l > r) return;
	if(lb[c] == l && rb[c] == r){
		seg[c] = x;
		return;
	}
	int k = (lb[c] + rb[c])/2;
	if(l <= k && k < r){
		hUpdate(2*c, l, k, x);
		hUpdate(2*c+1, k+1, r, x);
	}else if(r <= k){
		hUpdate(2*c, l, r, x);
	}else{
		hUpdate(2*c+1, l, r, x);
	}
}
int hQuery(int c, int l, int r){
	if(seg[c] > seg[2*c]) seg[2*c] = seg[c];
	if(seg[c] > seg[2*c+1]) seg[2*c+1] = seg[c];
	if(lb[c] == l && rb[c] == r) return seg[c];
	int k = (lb[c] + rb[c])/2;
	if(l <= k && k < r){
		return max(hQuery(2*c, l, k), hQuery(2*c+1, k+1, r));
	}else if(r <= k){
		return hQuery(2*c, l, r);
	}else{
		return hQuery(2*c+1, l, r);
	}
}
int qidx;
int hFT[300005];
void hAdd(int idx, int amt){
	while(idx <= n+1){
		hFT[idx] += amt;
		idx += idx & -idx;
	}
}
int hSum(int idx){
	int ret = 0;
	while(idx > 0){
		ret += hFT[idx];
		idx -= idx & -idx;
	}
	return ret;
}

/**
 * Returns the queries index i where i-th query is toggle something in range l, r
 * Complexity: O(log N)
 * Uses a max-lazy segment tree
 */
int lastProcessed(int l, int r){
	return hQuery(1, l, r);
}
/**
 * Find rightmost i such that state[i] == 0 but i < x or returns 0 if not exists
 * Complexity: O(log^2 N)
 * Binary search on fenwick tree
 */
int getRightmostZero(int x){
	int lo = 0;
	int hi = x-1;
	int s = hSum(x-1);
	while(lo < hi){
		int mid = (lo+hi+1)/2;
		if(hSum(mid-1) == s){
			hi = mid-1;
		}else{
			lo = mid;
		}
	}
	return lo;
}
/**
 * Find leftmost i such that state[i] == 0 but i > x or returns n+1 if not exists
 * Complexity: O(log^2 N)
 * Binary search on fenwick tree
 */
int getLeftmostZero(int x){
	int lo = x+1;
	int hi = n+1;
	int s = hSum(x);
	while(lo < hi){
		int mid = (lo+hi)/2;
		if(hSum(mid) == s){
			lo = mid+1;
		}else{
			hi = mid;
		}
	}
	return lo;
}
/**
 * Returns whether there are some zeroes in the range l, r ?
 * Complexity: O(log^2 N)
 */
bool hasZero(int l, int r){
	return getLeftmostZero(l-1) <= r;
}
int query(int l, int r){
	if(!hasZero(l, r)){
		// if all l -- r is 1,
		return sum(l,r) + qidx - lastProcessed(l, r);
	}else{
		// elif some l -- r is 0
		return sum(l,r);
	}
}
void toggle(int i){
	int l = getRightmostZero(i);
	int r = getLeftmostZero(i);
	if(state[i] == '1'){
		// toggle 1 to 0: find rightmost left 0, leftmost right 0
		// let them be l, r
		// (all subintervals) stats[l+1][r-1] += i - lastProcessed(l, r)
		int d = qidx - lastProcessed(l, r);
		add(l+1, 1, d);
		add(l+1, r, -d);
	}else{
		// toggle 0 to 1: find rightmost left 0, leftmost right 0
		// let them be l, r
		// (all subintervals) stats[l+1][i-1] += i - lastProcessed(l, i)
		// (all subintervals) stats[i+1][r-1] += i - lastProcessed(i, r)
		int dl = qidx - lastProcessed(l, i);
		add(l+1, 1, dl);
		add(l+1, i, -dl);
		int dr = qidx - lastProcessed(i, r);
		add(i+1, 1, dr);
		add(i+1, r, -dr);
	}
	hUpdate(1, l+1, r-1, qidx);
	if(state[i] == '0') hAdd(i, -1);
	else hAdd(i, 1);
	state[i] = '0'+'1'-state[i];
}
int main(){
	int q;
	scanf("%d%d",&n,&q);
	hBuild(1, 0, n+1);
	scanf("%s", state+1);
	for(int i = 1; i <= n; i++){
		if(state[i] == '0') hAdd(i, 1);
	}
	for(int i = 0; i < q; i++){
		char str[32];
		int l, r = 0;
		scanf("%s%d",str,&l);
		if(str[0] == 'q') scanf("%d",&r);
		r--;
		queries.emplace_back(str[0], l, r);
		if(str[0] == 'q') build(l, r);
	}
	finalizeBuild(n);
	for(qidx = 0; qidx < q; qidx++){
		char c; int l, r;
		tie(c, l, r) = queries[qidx];
		if(c == 'q'){
			printf("%d\n", query(l, r));
		}else{
			toggle(l);
		}
	}
}

Compilation message

street_lamps.cpp: In function 'void add(int, int, int)':
street_lamps.cpp:30:21: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   30 |   for(int j = st; j <= vectorBlock[i].size(); j += j & -j){
      |                   ~~^~~~~~~~~~~~~~~~~~~~~~~~
street_lamps.cpp: In function 'int main()':
street_lamps.cpp:198:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  198 |  scanf("%d%d",&n,&q);
      |  ~~~~~^~~~~~~~~~~~~~
street_lamps.cpp:200:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  200 |  scanf("%s", state+1);
      |  ~~~~~^~~~~~~~~~~~~~~
street_lamps.cpp:207:8: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  207 |   scanf("%s%d",str,&l);
      |   ~~~~~^~~~~~~~~~~~~~~
street_lamps.cpp:208:26: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  208 |   if(str[0] == 'q') scanf("%d",&r);
      |                     ~~~~~^~~~~~~~~
# Verdict Execution time Memory Grader output
1 Incorrect 19 ms 28544 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 269 ms 34800 KB Output isn't correct
2 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 21 ms 28672 KB Output is correct
2 Correct 21 ms 28800 KB Output is correct
3 Incorrect 22 ms 28920 KB Output isn't correct
4 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Correct 22 ms 28928 KB Output is correct
2 Correct 21 ms 28928 KB Output is correct
3 Correct 22 ms 28800 KB Output is correct
4 Correct 21 ms 28796 KB Output is correct
5 Runtime error 3584 ms 477464 KB Execution killed with signal 11
6 Halted 0 ms 0 KB -
# Verdict Execution time Memory Grader output
1 Incorrect 19 ms 28544 KB Output isn't correct
2 Halted 0 ms 0 KB -