cf-div.2-868-D

发布时间 2023-04-28 15:38:41作者: 安潇末痕

题目链接:https://codeforces.com/contest/1823/problem/D

比赛的时候关键性质已经想到,但没想到怎么正确构造。

性质:每次新加一个字母,回文子串的数量最多增加1(因为题目需要不相同的回文子串)。

证明:可以用反证法,易证。

构造方法:由于k的值很小(只有20),所以对于不再增加(回文子串)的字母串,用abc的循环节填充,否则就用一个新的字母填充。
比如用e添5个新的回文子串,构造为eeeee。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 2e5+10;
int K[N],X[N];
char ans[N];
void solve(){
    int n,c;
    cin>>n>>c;
    int sk = 0,sx = 0;
    int t = 0;
    bool flag = 1;
    bool f = 0;
    int val = 0;
    for (int i=1;i<=c;i++) cin>>K[i];
    for (int i=1;i<=c;i++) cin>>X[i];
    for (int i=1;i<=c;i++){
        f = 0;
        int k = K[i],x = X[i];
        if (k-sk<x-sx) {
            flag = 0;
            break;
        }
        else{
            while(sx<x){
                if (val<=2) ans[sk+1] = val+'a',val++;
                else {
                    ans[sk+1] = val+'a'; 
                    f = 1;
                }
                sx++;
                sk++;
            }
            if (f) val++;
            while(sk<k){
                ans[sk+1] = t+'a';
                t++;
                sk++;
                if (t==3) t = 0;
            }
        }
    }
    if (!flag) cout<<"NO\n";
    else{
        cout<<"YES\n";
        for (int i=1;i<=n;i++) cout<<ans[i];
        cout<<'\n';
    }
}
int main(){
    int T;
    T = 1;
    cin>>T;
    while(T--) solve();
    return 0;
}