题解:P8407 [COCI 2021/2022 #6] Superpozicija
Claire0918 · · 题解
我们知道一个括号序列合法,当且仅当将
如果
如果
我们现在确定了每个位置的贡献,枚举
Code:
#include<bits/stdc++.h>
#define mem(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 1e5 + 10;
int t, n;
char s[maxn << 1];
int a[maxn << 1], tag[maxn << 1], res[maxn];
vector<pair<int, int> > ad[maxn << 1];
priority_queue<pair<int, int>, vector<pair<int, int> >, greater<> > q;
int main(){
scanf("%d", &t);
while (t--){
scanf("%d %s", &n, s + 1), res[0] = 0;
for (int i = 1; i <= n << 1; a[i] = tag[i] = 0, ad[i].clear(), i++);
for (;!q.empty(); q.pop());
for (int i = 1; i <= n; i++){
int x, y;
scanf("%d %d", &x, &y);
if (s[x] == '(' && s[y] == '('){
res[i] = x > y, a[min(x, y)] = 1;
}else if (s[x] == ')' && s[y] == ')'){
res[i] = x < y, a[max(x, y)] = -1;
}else{
const bool tmp = s[x] == '(';
x > y && (swap(x, y), 1538), a[s[x] == '(' ? y : x] = -1, res[i] = tmp, ad[x].push_back(make_pair(y, tmp ? i : -i));
}
}
for (int i = 1; i <= n << 1; i++){
a[i] += a[i - 1] + tag[i];
for (auto x: ad[i]){
q.push(x);
}
if (a[i] < 0){
if (q.empty()){
res[0] = 1;
break;
}
a[i]++, (q.top().first > i ? tag[q.top().first] : a[i])++, res[abs(q.top().second)] = q.top().second < 0, q.pop();
}
}
if (res[0] || a[n << 1]){
printf("-1\n");
}else{
for (int i = 1; i <= n; i++){
printf("%d ", res[i]);
}
putchar('\n');
}
}
return 0;
}