C. Did We Get Everything Covered?

C. Did We Get Everything Covered?

You are given two integers n and k along with a string s.

Your task is to check whether all possible strings of length n that can be formed using the first k lowercase English alphabets occur as a subsequence of s. If the answer is NO, you also need to print a string of length n that can be formed using the first k lowercase English alphabets which does not occur as a subsequence of s.

If there are multiple answers, you may print any of them.

Note: A string a is called a subsequence of another string b if a can be obtained by deleting some (possibly zero) characters from b without changing the order of the remaining characters.

Input

The first line of input contains a single integer t(1t105), the number of test cases.

The first line of each test case contains 3 integers n(1n26),k(1k26),m(1m1000), where n and k are the same as described in the input and m is the length of the string s.

The second line of each test case contains a single string s of length m, comprising only of the first k lowercase English alphabets.

It is guaranteed that the sum of m and the sum of n over all test cases does not exceed 106.

Output

For each test case, print YES if all possible strings of length n that can be formed using the first k lowercase English alphabets occur as a subsequence of s, else print NO.

If your answer is NO, print a string of length n that can be formed using the first k lowercase English alphabets which does not occur as a subsequence of s in the next line.

You may print each letter of YES or NO in any case (for example, YES, yES, YeS will all be recognized as a positive answer).

Example

input

3
2 2 4
abba
2 2 3
abb
3 3 10
aabbccabab

output

YES
NO
aa
NO
ccc

Note

For the first test case, all possible strings (aa, ab, ba, bb) of length 2 that can be formed using the first 2 English alphabets occur as a subsequence of abba.

For the second test case, the string aa is not a subsequence of abb.

 

解题思路

  受 A 题 We Got Everything Covered! 的启发,如果将前 k 个字符构成一组,并把至少 n 组拼接成字符串,那么字符串所有的子序列一定包含 kn 种由前 k 个字符构成的长度为 n 的串。不过这只说明了充分性,并不能说明必要性,即如果某字符串所有的子序列包含由前 k 个字符构成的长度为 n 的串,则该字符串一定至少包含 n 个由前 k 个字符构成的组。比赛的时候没想到也没去猜所以没做出来。

  事实上这个必要性是成立的。我们依次找到 s 中由前 k 个字符构成的组,即依次遍历 s 的每个字符,用一个哈希表记录某个字符是否出现过,以及一个变量 c 统计当成组中有多少种字符。当遍历到 si,哈希表的 si 处记为 true,如果在变化之前为 falsec1。如果此时的 c=k,说明已经找到一组,清空哈希表和 c 继续找下一组。

  如果我们每次都选择每组中最后一个字符来尝试构成一个反例,显然如果字符串中小于 n 组,那么就一定可以构造出一个反例,只需将最后一组中没出现过的字符填到反例后面直到长度变成 n。这种构造方案也证明了必要性。

  AC 代码如下,时间复杂度为 O(m)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

const int N = 1010;

char s[N];
bool vis[26];

void solve() {
    int n, m, k;
    scanf("%d %d %d %s", &n, &k, &m, s);
    string ans;
    memset(vis, 0, sizeof(vis));
    for (int i = 0, c = 0; i < m; i++) {
        if (!vis[s[i] - 'a']) c++;
        vis[s[i] - 'a'] = true;
        if (c == k) {
            ans.push_back(s[i]);
            memset(vis, 0, sizeof(vis));
            c = 0;
        }
    }
    if (ans.size() >= n) {
        printf("YES\n");
    }
    else {
        printf("NO\n");
        for (int i = 0; i < 26; i++) {
            if (!vis[i]) {
                while (ans.size() < n) {
                    ans.push_back('a' + i);
                }
                printf("%s\n", ans.c_str());
                return;
            }
        }
    }
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        solve();
    }
    
    return 0;
}

 

参考资料

  Codeforces Round 921 (Div. 1, Div. 2) Editorial:https://codeforces.com/contest/1925/problem/C

posted @   onlyblues  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效
Web Analytics
点击右上角即可分享
微信分享提示