ARC153

发布时间 2023-07-17 23:10:09作者: HQJ2007

[ARC153A] AABCDDEFE

第一眼看上去让人以为是数位 DP,但看一眼样例 2 就知道直接枚举就行了。

六层循环暴力枚举。

复杂度 \(O(10^6)\)

[ARC153B] Grid Rotations

有思维含量的一题。

我们横纵坐标分开考虑,对于每一个矩形,每次操作会使其内部元素的横坐标上下对调。

纵坐标也同理,左右对调。

而这种反转操作我们显然可以直接用两棵文艺平衡树维护,复杂度 \(O(n\log n)\)

标程的做法更巧妙一下。我们可以把一条链收尾相接,两段序列的反转就相当于圆的反转。

所以我们可以只定位其中两个点,然后根据其最终位置填补出剩下元素。复杂度 \(O(n)\)

[ARC153C] ± Increasing Sequence

调整调整调整!

\(x=[1,2,3...n]\),则 \(sum=\sum\limits_{i=1}^{n}x_i\cdot a_i\)

调整的方法有两种,\(x\) 前缀 \(-1\)\(x\) 后缀 \(+1\)

然后我们发现,如果 \(x\) 存在正前缀和,则必然存在和为 \(1\) 的前缀;如果 \(x\) 存在负前缀和,则必然存在和为 \(-1\) 的前缀。后缀同理。

所以直接根据 \(sum\) 的正负,找前缀 \(1\),前缀 \(-1\),后缀 \(1\),后缀 \(-1\) 进行相应的调整即可。

复杂度 \(O(n)\)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 5;
ll n, a[N], ans[N], sum[N], s = 0;
int main() {
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
	cin >> n;
	for (int i = 1; i <= n; ++i) cin >> a[i];
	for (int i = 1; i <= n; ++i) ans[i] = i;
	for (int i = 1; i <= n; ++i) s += a[i] * i, sum[i] = sum[i - 1] + a[i];
	int p1 = -1, p2 = -1, p3 = -1, p4 = -1;
	for (int i = 1; i <= n; ++i) {
		if (sum[i] == -1) p1 = i;
		if (sum[i] == 1) p2 = i;
		if (s - sum[i - 1] == -1) p3 = i;
		if (s - sum[i - 1] == 1) p4 = i;
	}
	if (s > 0) {
		if (p3 != -1) for (int i = p3; i <= n; ++i) ans[i] += s;
		else if (p2 != -1) for (int i = 1; i <= p2; ++i) ans[i] -= s;
	} else {
		if (p4 != -1) for (int i = p4; i <= n; ++i) ans[i] -= s;
		else if (p1 != -1) for (int i = 1; i <= p1; ++i) ans[i] += s;
	}
	ll tmp = 0;
	for (int i = 1; i <= n; ++i) tmp += ans[i] * a[i];
	if (tmp == 0) {
		cout << "Yes" << endl;
		for (int i = 1; i <= n; ++i) cout << ans[i] << " ";
		cout << endl;
	} else cout << "No" << endl;
	return 0;
}