제출 #568894

#제출 시각아이디문제언어결과실행 시간메모리
568894HappyPacManStreet Lamps (APIO19_street_lamps)C++14
100 / 100
3679 ms156196 KiB
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5 + 2;
vector<int> ord[4*maxn],bit[4*maxn];

// order preprocessing
void updOrd(int i,int l,int r,int u,int v){
	if(l == r){
		ord[i].emplace_back(v);
	}else{
		int m = (l+r)/2;
		ord[i].emplace_back(v);
		if(u <= m){
			updOrd(i<<1,l,m,u,v);
		}else{
			updOrd(i<<1|1,m+1,r,u,v);
		}
	}
}

// Binary Indexed Tree on Segment Tree
void BitUpd(int t,int u,int v){
	for(++u;u<=bit[t].size();u+=u&(-u)){
		bit[t][u-1] += v;
	}
}
int BitQry(int t,int u){
	int res = 0;
	for(++u;u>0;u-=u&(-u)){
		res += bit[t][u-1];
	}
	return res;
}

void SegUpd(int i,int l,int r,int u,int v,int w){
	int idx = lower_bound(ord[i].begin(),ord[i].end(),v)-ord[i].begin();
	if(l == r){
		BitUpd(i,idx,w);
	}else{
		int m = (l+r)/2;
		BitUpd(i,idx,w);
		if(u <= m){
			SegUpd(i<<1,l,m,u,v,w);
		}else{
			SegUpd(i<<1|1,m+1,r,u,v,w);
		}
	}
}
int SegQry(int i,int l,int r,int ql,int qr,int v){
	int idx = upper_bound(ord[i].begin(),ord[i].end(),v)-ord[i].begin()-1;
	if(l > qr || r < ql){
		return 0;
	}else if(ql <= l && r <= qr){
		return BitQry(i,idx);
	}else{
		int m = (l+r)/2;
		return SegQry(i<<1,l,m,ql,qr,v)+SegQry(i<<1|1,m+1,r,ql,qr,v);
	}
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int N,Q;
	string S;
	cin >> N >> Q >> S;
	set<pair<int,int> > range;
	int start = 0;
	for(int i=0;i<N;i++){
		if(S[i] == '0'){
			if(start != i){
				range.emplace(start,i-1);
				updOrd(1,0,N-1,i-1,start);
			}
			start = i+1;
		}
	}
	if(start != N){
		range.emplace(start,N-1);
		updOrd(1,0,N-1,N-1,start);
	}
	vector<pair<int,int> > query;
	while(Q--){
		string tp;
		cin >> tp;
		// toggle tested
		if(tp == "toggle"){
			int i;
			cin >> i;
			query.emplace_back(i,-1);
			if(range.upper_bound(make_pair(i,-1)) == range.begin() || (*prev(range.upper_bound(make_pair(i,-1)))).second < i-1){
				int li = i-1, ri = i-1;
				if(range.upper_bound(make_pair(i,-1)) != range.begin() && (*prev(range.upper_bound(make_pair(i,-1)))).second == i-2){
					li = (*prev(range.upper_bound(make_pair(i,-1)))).first;
					range.erase(prev(range.upper_bound(make_pair(i,-1))));
				}
				if(range.upper_bound(make_pair(i,-1)) != range.end() && (*range.upper_bound(make_pair(i,-1))).first == i){
					ri = (*range.upper_bound(make_pair(i,-1))).second;
					range.erase(range.upper_bound(make_pair(i,-1)));
				}
				updOrd(1,0,N-1,ri,li);
				range.emplace(li,ri);
			}else{
				auto [li,ri] = *prev(range.upper_bound(make_pair(i,-1)));
				range.erase(prev(range.upper_bound(make_pair(i,-1))));
				if(li < i-1){
					range.emplace(li,i-2);
					updOrd(1,0,N-1,i-2,li);
				}
				if(ri > i-1){
					range.emplace(i,ri);
					updOrd(1,0,N-1,ri,i);
				}
			}
		}else{
			int a,b;
			cin >> a >> b;
			query.emplace_back(a,b);
		}
	}
	for(int i=0;i<4*maxn;i++){
		sort(ord[i].begin(),ord[i].end());
		ord[i].erase(unique(ord[i].begin(),ord[i].end()),ord[i].end());
		bit[i].resize(ord[i].size(),0);
	}
	range.clear();
	map<pair<int,int>,int> lastIdx;
	start = 0;
	for(int i=0;i<N;i++){
		if(S[i] == '0'){
			if(start != i){
				range.emplace(start,i-1);
				lastIdx[make_pair(start,i-1)] = 0;
			}
			start = i+1;
		}
	}
	if(start != N){
		range.emplace(start,N-1);
		lastIdx[make_pair(start,N-1)] = 0;
	}
	int curIdx = 1;
	for(auto [i,j] : query){
		if(j == -1){
			if(range.upper_bound(make_pair(i,-1)) == range.begin() || (*prev(range.upper_bound(make_pair(i,-1)))).second < i-1){
				int li = i-1, ri = i-1;
				if(range.upper_bound(make_pair(i,-1)) != range.begin() && (*prev(range.upper_bound(make_pair(i,-1)))).second == i-2){
					li = (*prev(range.upper_bound(make_pair(i,-1)))).first;
					auto [lj,rj] = *prev(range.upper_bound(make_pair(i,-1)));
					SegUpd(1,0,N-1,rj,lj,curIdx-lastIdx[make_pair(lj,rj)]);
					range.erase(prev(range.upper_bound(make_pair(i,-1))));
				}
				if(range.upper_bound(make_pair(i,-1)) != range.end() && (*range.upper_bound(make_pair(i,-1))).first == i){
					ri = (*range.upper_bound(make_pair(i,-1))).second;
					auto [lj,rj] = *range.upper_bound(make_pair(i,-1));
					SegUpd(1,0,N-1,rj,lj,curIdx-lastIdx[make_pair(lj,rj)]);
					range.erase(range.upper_bound(make_pair(i,-1)));
				}
				lastIdx[make_pair(li,ri)] = curIdx;
				range.emplace(li,ri);
			}else{
				auto [li,ri] = *prev(range.upper_bound(make_pair(i,-1)));
				range.erase(prev(range.upper_bound(make_pair(i,-1))));
				SegUpd(1,0,N-1,ri,li,curIdx-lastIdx[make_pair(li,ri)]);
				if(li < i-1){
					lastIdx[make_pair(li,i-2)] = curIdx;
					range.emplace(li,i-2);
				}
				if(ri > i-1){
					lastIdx[make_pair(i,ri)] = curIdx;
					range.emplace(i,ri);
				}
			}
		}else{
			int res = SegQry(1,0,N-1,j-2,N-1,i-1);
			if(range.upper_bound(make_pair(i,-1)) != range.begin() && (*prev(range.upper_bound(make_pair(i,-1)))).second >= j-2){
				auto [lj,rj] = *prev(range.upper_bound(make_pair(i,-1)));;
				res += curIdx-lastIdx[make_pair(lj,rj)];
			}
			cout << res << '\n';
		}
		curIdx++;
	}
}

컴파일 시 표준 에러 (stderr) 메시지

street_lamps.cpp: In function 'void BitUpd(int, int, int)':
street_lamps.cpp:23:11: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
   23 |  for(++u;u<=bit[t].size();u+=u&(-u)){
      |          ~^~~~~~~~~~~~~~~
street_lamps.cpp: In function 'int main()':
street_lamps.cpp:105:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  105 |     auto [li,ri] = *prev(range.upper_bound(make_pair(i,-1)));
      |          ^
street_lamps.cpp:144:11: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  144 |  for(auto [i,j] : query){
      |           ^
street_lamps.cpp:150:11: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  150 |      auto [lj,rj] = *prev(range.upper_bound(make_pair(i,-1)));
      |           ^
street_lamps.cpp:156:11: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  156 |      auto [lj,rj] = *range.upper_bound(make_pair(i,-1));
      |           ^
street_lamps.cpp:163:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  163 |     auto [li,ri] = *prev(range.upper_bound(make_pair(i,-1)));
      |          ^
street_lamps.cpp:178:10: warning: structured bindings only available with '-std=c++17' or '-std=gnu++17'
  178 |     auto [lj,rj] = *prev(range.upper_bound(make_pair(i,-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...