CF1775E The Human Equation

CF1775E The Human Equation

题目大意:

给定 \(n\) 个数 \(a_1...a_n\),随后你可以进行若干次操作,每次操作步骤如下:

  • 选出 \(a\) 中一个子序列(可以不连续)。

  • 把子序列中的奇数项减一,偶数项加一;或者奇数项加一,偶数项减一。

求把 \(n\) 个数全部变成 \(0\) 的最少操作次数。

思路:

先把输入的 \(a\) 数组看作一个差分数组,然后构造 \(b\) 数组为差分数组 \(a\) 的“原序列”。

例如:

读入 \(a[2,-4,3,-5,4]\),则 \(b[2,-2,1,-4,0]\)。我们选择 \(a\) 的子序列 \([-4,3,-5]\) 进行操作,奇数项加,偶数项减。

则修改后的数组为 \(a[2,(-4+1=)-3,(3-1=)2,(-5+1=)-4,4]\\b[2,(-2+1=)-1,(1+1-1=)1,(-4+1=)-3,(0+1=)1]\),其变化为 \(b_2+1,b[4,5]+1\)

继续观察多组后可以发现:

  • 若修改 \(a\) 中子序列 \([x_1,\cdots,x_m]\),奇数项加,偶数项减,则 \(b\) 的变化是 \(b[x_1,x_2)+1,b[x_3,x_4)+1,\cdots\)
  • 若修改 \(a\) 中子序列 \([x_1,\cdots,x_m]\),奇数项减,偶数项加,则 \(b\) 的变化是 \(b[x_1,x_2)-1,b[x_3,x_4)-1,\cdots\)

所以原题目变成:给你一个数组 \(b\),每次可以选择一个区间 \([i,j]\) 使这个区间里的所有值都 \(+1\)\(-1\),问最少多少次把最大的和最小值都变为 \(0\)

那么取极差即可。

代码:

#include <bits/stdc++.h>
#define ll long long
#define Maxn 200005

using namespace std;

ll T, n, a[Maxn], b[Maxn], tot = 0;
ll maxl, minl;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	
	cin >> T;
while (T --) {
	cin >> n;
	for (ll i = 1; i <= n; i ++) {
		cin >> a[i];
	}
	
	tot = 1, b[1] = 0;
	for (ll i = 1; i <= n; i ++) {
		if (a[i] == 0) { continue; }
		if (b[tot] == 0) {
			b[tot] = a[i]; continue;
		}
		
		if (b[tot] < 0) {
			if (a[i] < 0) { b[tot] += a[i]; }
			else { b[++ tot] = a[i]; }
		} else {
			if (a[i] > 0) { b[tot] += a[i]; }
			else { b[++ tot] = a[i]; }
		}
	}
	
//	if (tot == 1) {
//		cout << abs(b[1]) << "\n";
//		continue;
//	}
	
	maxl = minl = 0;
	for (ll i = 1; i <= tot; i ++) {
		a[i] = a[i - 1] + b[i];
		maxl = max(maxl, a[i]);
		minl = min(minl, a[i]);
	} cout << maxl - minl << "\n";
} return 0;
}
posted @ 2024-11-24 10:04  BLM-dolphin  阅读(31)  评论(0)    收藏  举报