「CF286C」Main Sequence

传送门
Luogu

解题思路

看到正负号相互抵消,很容易联想到括号匹配和栈。
但由于题目钦定了一些位置只能是负数,所以我们可以这样考虑:
把负数视为右括号,正数视为左括号,然后开一个栈,从右往左遍历,能匹配就匹配。
如果能匹配但是不匹配,一定不会更优,这是显然易见的。

细节注意事项

  • 咕咕咕

参考代码

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
	s = 0; int f = 0; char c = getchar();
	while (!isdigit(c)) f |= c == '-', c = getchar();
	while (isdigit(c)) s = s * 10 + c - 48, c = getchar();
	s = f ? -s : s;
}

const int _ = 1000010;

int n, m, a[_], t[_], bo[_], top, stk[_];

int main() {
#ifndef ONLINE_JUDGE
	freopen("in.in", "r", stdin);
#endif
	read(n);
	for (rg int i = 1; i <= n; ++i) read(a[i]);
	read(m);
	for (rg int x, i = 1; i <= m; ++i) read(x), bo[x] = 1;
	top = 0;
	for (rg int i = n; i >= 1; --i) {
		if (a[i] != a[stk[top]] || bo[i]) stk[++top] = i, t[i] = -1;
		else t[i] = 1, --top;
	}
	if (top) { puts("NO"); return 0; }
	puts("YES");
	for (rg int i = 1; i <= n; ++i)
		printf("%d%c", a[i] * t[i], " \n"[i == n]);
	return 0;
}

完结撒花 \(qwq\)

posted @ 2019-10-27 07:46  Sangber  阅读(135)  评论(0编辑  收藏  举报