Educational Codeforces Round 102 (Rated for Div. 2)D. Program

D. Program

题意

给你一个\(x\)初始值为0,然后给你一系列\(+-\)操作,问你忽略掉\([l, r]\)区间的操作后,经过一系列操作,操作过程中会出现多少个不同的数字。比如说:0,1,2算三种,0,1, 0算2种

思路

容易发现一个区间\([x,y]\)其中出现的数的可能有\(max([x,y])-min([x,y])\)但是需要注意和0的关系问题,因为\(x\)的初始值为0。

三种情况分情况讨论:

[l,r]在最左部分也就是有效部分为[x,n],此时\(max([x,n]) - min([x, n])\)然后判断和0的关系

[l,r]在最右部分也就是有效部分为[1,x],此时\(max([1,x]) - min([1,x])\)然后判断和0的关系

如果[l,r在中间]那么我们将右面的部分减去[l,r]之间的影响值,也就是将左右两部分合并。

因为中间对右面的影响是固定值:\(a[r] - a[l - 1]\),然后同上和0讨论。

#include<bits/stdc++.h>

using namespace std;
const int N = 2e5 + 10;
const int lgn = 21;
//#define int long long

int qmax[N][21], qmin[N][21];
int lg[N];
void init() {
	lg[1] = 0, lg[2] = 1;
	for (int i = 3; i < N; ++i)lg[i] = lg[i >> 1] + 1;
}

void st(int n) {
	for (int j = 1; j < lgn; ++j) {
		for (int i = 1; i + (1 << j) - 1 <= n; ++i) {
			qmax[i][j] = max(qmax[i][j - 1], qmax[i+ (1 << (j - 1))][j - 1]);
			qmin[i][j] = min(qmin[i][j - 1], qmin[i+ (1 << (j - 1))][j - 1]);
		}
	}
}

int lmax(int l, int r) {
	int len = lg[r - l + 1];
	return max(qmax[l][len], qmax[r - (1 << len) + 1][len]);
}

int lmin(int l, int r) {
	int len = lg[r - l + 1];
	return min(qmin[l][len], qmin[r - (1 << len) + 1][len]);
}

int psum[N];

int cal(int l1, int r1 ,int l2, int r2) {
	r1 = max({r1, r2, 0});
	l1 = min({l1 , l2, 0});
	return r1 - l1 + 1;
}
void solve() {
	int n, m; cin >> n >> m;
	string str; cin >> str;
	for (int i = 0; i < str.size(); ++i) {
		if (str[i] == '+') psum[i + 1] = psum[i] + 1;
		else psum[i + 1] = psum[i] - 1;
		qmax[i + 1][0] = qmin[i + 1][0] = psum[i + 1];
	}
	st(n);
	while (m --) {
		int l, r; cin >> l >> r;
		int l1, r1, l2, r2;
		if (l == 1) {
			l1 = 0;
			r1 = 0;
		} else {
			l1 = lmin(1, l - 1);
			r1 = lmax(1, l - 1);
		}
		if (r == n) l2 = 0, r2 = 0;
		else {
			l2 = lmin(r + 1, n);
			r2 = lmax(r + 1, n);
			l2 -= psum[r] - psum[l - 1];
			r2 -= psum[r] - psum[l - 1];
		}
		cout << cal(l1 ,r1 ,l2 ,r2) << endl;
	}
}


signed main() {
	init();
	ios::sync_with_stdio(false);
	cin.tie(0);
    int T = 1;
    cin >> T;
    while (T--) {
        solve();
    }

}
上一篇:【ZooKeeper】从基础知识到应用实践


下一篇:极客日报第 21 期:360 安全浏览器尝试收费;苹果macOS首次出现在云端