답안 #497271

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
497271 2021-12-22T22:17:37 Z aryan12 Growing Trees (BOI11_grow) C++17
0 / 100
166 ms 19008 KB
#include <bits/stdc++.h>
using namespace std;
#define int long long

mt19937_64 RNG(chrono::steady_clock::now().time_since_epoch().count());

const int N = 1e5 + 5, INF = 1e15;
vector<int> a(N);
int n, q;

struct range {
	int minval, maxval, lazyval;

	range() {
		minval = 0;
		maxval = 0;
		lazyval = 0;
	}
} *seg[N * 4];

void FixLazy(int l, int r, int pos) {
	seg[pos]->maxval += seg[pos]->lazyval;
	seg[pos]->minval += seg[pos]->lazyval;
	if(l == r) {
		seg[pos]->lazyval = 0;
		return;
	}
	seg[pos * 2]->lazyval += seg[pos]->lazyval;
	seg[pos * 2 + 1]->lazyval += seg[pos]->lazyval;
	seg[pos]->lazyval = 0;
}

void Upd(int l, int r, int pos, int ql, int qr, int qval) {
	if(seg[pos]->lazyval != 0) {
		FixLazy(l, r, pos);
	}
	if(ql > r || l > qr) {
		return;
	}
	if(l == r) {
		seg[pos]->minval += qval;
		seg[pos]->maxval += qval;
		return;
	}
	if(ql <= l && r <= qr) {
		seg[pos]->minval += qval;
		seg[pos]->maxval += qval;
		seg[pos * 2]->lazyval += qval;
		seg[pos * 2 + 1]->lazyval += qval;
		return;
	}
	int mid = (l + r) >> 1;
	Upd(l, mid, pos * 2, ql, qr, qval);
	Upd(mid + 1, r, pos * 2 + 1, ql, qr, qval);
	seg[pos]->minval = min(seg[pos * 2]->minval, seg[pos * 2 + 1]->minval);
	seg[pos]->maxval = max(seg[pos * 2]->maxval, seg[pos * 2 + 1]->maxval);
}

int GetValue(int l, int r, int pos, int qpos) {
	if(seg[pos]->lazyval != 0) {
		FixLazy(l, r, pos);
	}
	if(l == r) {
		return seg[pos]->maxval;
	}
	int mid = (l + r) >> 1;
	if(qpos <= mid) {
		return GetValue(l, mid, pos * 2, qpos);
	}
	return GetValue(mid + 1, r, pos * 2 + 1, qpos);
}

int FindIdx(int l, int r, int pos, int qval) {
	if(seg[pos]->lazyval != 0) {
		FixLazy(l, r, pos);
	}
	if(seg[pos]->maxval <= qval) {
		return r;
	}
	if(seg[pos]->minval > qval) {
		return l - 1;
	}
	int mid = (l + r) >> 1;
	int x = FindIdx(l, mid, pos * 2, qval);
	if(x == mid) {
		return FindIdx(mid + 1, r, pos * 2 + 1, qval);
	}
	return x;
}

void Output(int l, int r, int pos) {
	if(seg[pos]->lazyval != 0) {
		FixLazy(l, r, pos);
	}
	if(l == r) {
		cout << seg[pos]->maxval << " ";
		return;
	}
	int mid = (l + r) >> 1;
	Output(l, mid, pos * 2);
	Output(mid + 1, r, pos * 2 + 1);
}

void Solve() {
	for(int i = 0; i < N * 4; i++) {
		seg[i] = new range();
	}
	cin >> n >> q;
	for(int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	sort(a.begin() + 1, a.begin() + 1 + n);
	for(int i = 1; i <= n; i++) {
		//cout << "a[i] = " << a[i] << "\n";
		Upd(1, n, 1, i, i, a[i]);
	}
	for(int i = 1; i <= q; i++) {
		char command;
		cin >> command;
		if(command == 'F') {
			int freq, atleast;
			cin >> freq >> atleast;
			if(seg[1]->maxval < atleast) {
				continue;
			}
			int startfrom = FindIdx(1, n, 1, atleast - 1) + 1;
			//cout << "How many trees? " << freq << ", Min height? " << atleast << "\n";
			//cout << "startfrom = " << startfrom << "\n";
			int lastPos = min(n, startfrom + freq - 1);
			//cout << "lastPos = " << lastPos << "\n";
			int lastValue = GetValue(1, n, 1, lastPos);
			//cout << "lastValue = " << lastValue << "\n";
			int changesRequired = FindIdx(1, n, 1, lastValue - 1);
			//cout << "changesRequired = " << changesRequired << "\n";
			Upd(1, n, 1, startfrom, changesRequired, 1);
			int freqLeft = freq - (changesRequired - startfrom + 1);
			//cout << "freqLeft = " << freqLeft << "\n";
			lastPos = FindIdx(1, n, 1, lastValue);
			//cout << "lastPos = " << lastPos << "\n";
			Upd(1, n, 1, lastPos - freqLeft + 1, lastPos, 1);
		}
		else {
			int minx, maxx;
			cin >> minx >> maxx;
			cout << FindIdx(1, n, 1, maxx) - FindIdx(1, n, 1, minx - 1) << "\n";
		}
		//cout << "Seg tree at the end looks like:\n";
		//Output(1, n, 1);
		//cout << "\n";
		/*for(int j = 1; j < n; j++) {
			if(GetValue(1, n, 1, j) > GetValue(1, n, 1, j + 1)) {
				assert(false);
			}
		}*/
	}
}

int32_t main() {
	auto begin = std::chrono::high_resolution_clock::now();
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int t = 1;
	//cin >> t;
	while(t--) {
		Solve();
	}
	auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
    cerr << "Time measured: " << elapsed.count() * 1e-9 << " seconds.\n"; 
	return 0;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 102 ms 17988 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 16 ms 16772 KB Output is correct
2 Correct 16 ms 16784 KB Output is correct
3 Incorrect 17 ms 16780 KB Output isn't correct
4 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 52 ms 17888 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 43 ms 17956 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 87 ms 17832 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 121 ms 17808 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 76 ms 17756 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 166 ms 18456 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 138 ms 18172 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 152 ms 19008 KB Output isn't correct