結果
| 問題 |
No.2107 Entangled LIS
|
| コンテスト | |
| ユーザー |
Sumitacchan
|
| 提出日時 | 2022-09-03 16:43:41 |
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 108 ms / 2,000 ms |
| コード長 | 4,061 bytes |
| コンパイル時間 | 1,983 ms |
| コンパイル使用メモリ | 202,776 KB |
| 最終ジャッジ日時 | 2025-02-07 02:24:26 |
|
ジャッジサーバーID (参考情報) |
judge2 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 1 |
| other | AC * 10 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
struct fast_ios { fast_ios(){ cin.tie(0); ios::sync_with_stdio(false); cout << fixed << setprecision(20); }; } fast_ios_;
#define FOR(i, begin, end) for(int i=(begin);i<(end);i++)
#define REP(i, n) FOR(i,0,n)
#define IFOR(i, begin, end) for(int i=(end)-1;i>=(begin);i--)
#define IREP(i, n) IFOR(i,0,n)
const int INF = 1000000000;
void solve(int N, int A, int B, string s, vector<int> &a, vector<int> &b, bool &is_ok){
a.resize(N);
b.resize(N);
if(N == 0){
assert(s.size() == 0);
return;
}
assert(1 <= A && A <= N);
assert(1 <= B && B <= N);
assert((int)s.size() == N);
bool flip = false;
if(A > B){
swap(A, B);
REP(i, N){
if(s[i] == 'a') s[i] = 'b';
else if(s[i] == 'b') s[i] = 'a';
else assert(false);
}
flip = true;
}
if(A == N && B == N){
REP(i, N){
a[i] = 2 * i, b[i] = 2 * i + 1;
if(s[i] == 'a') swap(a[i], b[i]);
}
}else if(A == 1 && B == 1){
REP(i, N){
a[i] = 2 * (N - 1 - i), b[i] = 2 * (N - 1 - i) + 1;
if(s[i] == 'a') swap(a[i], b[i]);
}
}else if(A == 2 && B == N){
bool f = false;
REP(i, N - 1){
if(s[i] == 'b' && s[i + 1] == 'a') f = true;
}
int i0, now;
if(f){
i0 = 0, now = 0;
}else{
a[0] = 0, b[0] = 1;
if(s[0] == 'a') swap(a[0], b[0]);
i0 = 1, now = 2;
}
IFOR(i, i0, N){
if(s[i] == 'b') a[i] = now++;
}
FOR(i, i0, N){
b[i] = now++;
}
IFOR(i, i0, N){
if(s[i] == 'a') a[i] = now++;
}
assert(now == 2 * N);
}else if(A >= 2){
vector<int> a1, a2, a3, b1, b2, b3;
int N1 = A - 2, N2 = B - A + 2, N3 = N - B;
solve(N1, N1, N1, s.substr(0, N1), a1, b1, is_ok);
solve(N2, 2, N2, s.substr(N1, N2), a2, b2, is_ok);
solve(N3, 1, 1, s.substr(N1 + N2, N3), a3, b3, is_ok);
REP(i, N1){
a[i] = a1[i] + 2 * N3;
b[i] = b1[i] + 2 * N3;
}
REP(i, N2){
a[N1 + i] = a2[i] + 2 * (N1 + N3);
b[N1 + i] = b2[i] + 2 * (N1 + N3);
}
REP(i, N3){
a[N1 + N2 + i] = a3[i];
b[N1 + N2 + i] = b3[i];
}
}else if(A == 1){
int n = -1;
// 'a'=0, 'b'=1 として広義LISを求める
vector<int> dp(N, INF);
REP(i, N){
int x = s[i] - 'a';
assert(x == 0 || x == 1);
auto it = upper_bound(dp.begin(), dp.end(), x);
int k = distance(dp.begin(), it);
dp[k] = x;
if(k + 1 == B){
// 最初からn項までに限れば広義LIS長はB
n = i + 1;
break;
}
}
if(n == -1){
is_ok = false;
return;
}
int now = 0;
IFOR(i, n, N){
a[i] = now++;
b[i] = now++;
if(s[i] == 'a') swap(a[i], b[i]);
}
FOR(i, 0, n){
if(s[i] == 'a') b[i] = now++;
}
IFOR(i, 0, n){
a[i] = now++;
}
FOR(i, 0, n){
if(s[i] == 'b') b[i] = now++;
}
}else{
assert(false);
}
if(flip){
REP(i, N){
swap(a[i], b[i]);
}
}
}
int main(){
int T; cin >> T;
REP(test_case, T){
int N, A, B; cin >> N >> A >> B;
string s; cin >> s;
vector<int> a, b;
bool is_ok = true;
solve(N, A, B, s, a, b, is_ok);
if(is_ok){
cout << "Yes" << endl;
REP(i, N){
cout << a[i] + 1 << ' ';
}
cout << endl;
REP(i, N){
cout << b[i] + 1 << ' ';
}
cout << endl;
}else{
cout << "No" << endl;
}
}
}
Sumitacchan