「chaynOI R2 T1」构造字符串题解
P15036 「chaynOI R2 T1」构造字符串
题目描述
本题字符集 Σ={a,b,c}\Sigma = \{\text{a},\text{b},\text{c}\}Σ={a,b,c},即默认所有字符为 a,b,c\text{a},\text{b},\text{c}a,b,c 中的一个。
flow 有一个字符串 TTT 和一个初始为空的字符串 SSS,其中 ∣T∣=n|T|=n∣T∣=n,为了方便起见,保证 T1=a,T2=bT_1=\text{a},T_2=\text{b}T1=a,T2=b。
flow 有两种操作:
- 向 SSS 末尾添加一个字符 xxx,需要满足 ∄1≤i≤∣S∣,Si=x\nexists 1\le i\le |S|,S_i=x∄1≤i≤∣S∣,Si=x。
- 选择一个位置 iii 满足 2≤i≤∣S∣2\le i\le |S|2≤i≤∣S∣ 且 Si≠Si−1S_i\ne S_{i-1}Si=Si−1,将 SiS_iSi 修改为 xxx 满足 x∉{Si−1,Si}x\not\in\{S_{i-1},S_i\}x∈{Si−1,Si}(可以注意到,xxx 唯一)。
请你帮助 flow 在至多 10610^6106 次操作后将 SSS 修改为与 TTT 相同,输出任意一个合法的解均可。
数据保证有解。
输入格式
一行一个字符串 TTT。
输出格式
第一行一个正整数 kkk,表示你的操作次数,需要满足 1≤k≤1061\le k\le 10^61≤k≤106。
接下来 kkk 行,每行为 1 x 或 2 i,表示操作 111 加入字符 xxx 或操作 222 修改位置 iii。
输入输出样例 #1
输入 #1
abca
输出 #1
8
1 a
1 c
1 b
2 3
1 b
2 2
2 3
2 4
说明/提示
样例 1 解释
SSS 的变换过程为 []→[a]→[ac]→[acb]→[aca]→[acab]→[abab]→[abcb]→[abca]\text{[]}\to\text{[a]}\to\text{[ac]}\to\text{[acb]}\to\text{[aca]}\to\text{[acab]}\to\text{[abab]}\to\text{[abcb]}\to\text{[abca]}[]→[a]→[ac]→[acb]→[aca]→[acab]→[abab]→[abcb]→[abca]。
数据范围
本题采用捆绑测试。
对于 100%100\%100% 的数据,3≤n≤2222223\le n\le2222223≤n≤222222,Ti∈ΣT_i\in \SigmaTi∈Σ。
- Subtask1(10pts):n≤5n\le 5n≤5。
- Subtask2(10pts):n≤1000n\le 1000n≤1000。
- Subtask3(10pts):∀3≤i≤n\forall 3\le i\le n∀3≤i≤n,Ti=cT_i=\text{c}Ti=c。
- Subtask4(20pts):n≤2×105n\le 2\times10^5n≤2×105。
- Subtask5(50pts):无特殊限制。
思路
直接暴力构造,倒序实现。
代码见下
#include<bits/stdc++.h>
using namespace std;
string str;
char s[1000006],t[1000006];
struct one{
long long a;
char x;
long long i;
}a[1000006];
long long n,k;
int main(){
cin>>str;
for(int i=0;i<str.size();i++){
t[++n]=str[i];
}
s[1]=t[1];
s[2]=t[2];
a[++k]={1,'a',0};
a[++k]={1,'b',0};
for(int i=3;i<=n;i++){
a[++k]={1,'c',0};
a[++k]={2,' ',i};
if(i%2==1){
s[i]='a';
}
else{
s[i]='b';
}
}
for(int i=n;i>=1;i--){
if(s[i]!=t[i]){
if(s[i]=='a'){
if(t[i]=='b'){
a[++k]={2,' ',i-1};
a[++k]={2,' ',i};
s[i-1]='c';
}
else{
a[++k]={2,' ',i};
}
}
else if(s[i]=='b'){
if(t[i]=='a'){
a[++k]={2,' ',i-1};
a[++k]={2,' ',i};
s[i-1]='c';
}
else{
a[++k]={2,' ',i};
}
}
else{
if(t[i]=='a'){
if(s[i-1]=='b'){
a[++k]={2,' ',i};
}
else{
a[++k]={2,' ',i};
a[++k]={2,' ',i-1};
a[++k]={2,' ',i};
s[i-1]='c';
}
}
else{
if(s[i-1]=='a'){
a[++k]={2,' ',i};
}
else{
a[++k]={2,' ',i};
a[++k]={2,' ',i-1};
a[++k]={2,' ',i};
s[i-1]='c';
}
}
}
}
}
if(k<=1000000){
cout<<k<<endl;
for(int i=1;i<=k;i++){
if(a[i].a==1){
cout<<a[i].a<<" "<<a[i].x<<'\n';
}
else{
cout<<a[i].a<<" "<<a[i].i<<'\n';
}
}
}
else{
k=0;
n=0;
for(int i=0;i<str.size();i++){
t[++n]=str[i];
}
s[1]=t[1];
s[2]=t[2];
a[++k]={1,'a',0};
a[++k]={1,'b',0};
for(int i=3;i<=n;i++){
a[++k]={1,'c',0};
a[++k]={2,' ',i};
if(i%2==1){
s[i]='a';
}
else{
s[i]='b';
}
}
for(int i=n;i>=1;){
if(s[i]!=t[i]){
if(s[i]=='a'){
if(t[i]=='b'){
int u=i;
for(int j=i;j>=1;j--){
if(s[j]==t[j]||t[j]=='c'){
u=j+1;
break;
}
}
for(int j=u;j<=i;j+=2){
a[++k]={2,' ',j};
}
for(int j=u+1;j<=i;j+=2){
a[++k]={2,' ',j};
}
for(int j=u;j<=i;j+=2){
a[++k]={2,' ',j};
}
a[++k]={2,' ',u-1};
a[++k]={2,' ',u};
a[++k]={2,' ',u-1};
i=u-1;
}
else{
a[++k]={2,' ',i};
i--;
}
}
else{
if(t[i]=='a'){
int u=i;
for(int j=i;j>=1;j--){
if(s[j]==t[j]||t[j]=='c'){
u=j+1;
break;
}
}
for(int j=u;j<=i;j+=2){
a[++k]={2,' ',j};
}
for(int j=u+1;j<=i;j+=2){
a[++k]={2,' ',j};
}
for(int j=u;j<=i;j+=2){
a[++k]={2,' ',j};
}
a[++k]={2,' ',u-1};
a[++k]={2,' ',u};
a[++k]={2,' ',u-1};
i=u-1;
}
else{
a[++k]={2,' ',i};
i--;
}
}
}
else{
i--;
}
}
cout<<k<<endl;
for(int i=1;i<=k;i++){
if(a[i].a==1){
cout<<a[i].a<<" "<<a[i].x<<'\n';
}
else{
cout<<a[i].a<<" "<<a[i].i<<'\n';
}
}
}
return 0;
}```

浙公网安备 33010602011771号