「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\)