D. Unique Palindromes
D. Unique Palindromes
A palindrome is a string that reads the same backwards as forwards. For example, the string abcba is palindrome, while the string abca is not.
Let be the number of unique palindromic substrings of string , i. e. the number of substrings that are palindromes themselves. Even if some substring occurs in several times, it's counted exactly once. (The whole string is also counted as a substring of ).
For example, string abcbbcabcb has unique palindromic substrings: a, b, c, bb, bcb and cbbc.
Now, let's define where . In other words, is the number of palindromic substrings in the prefix of of length . For example, abcbbcabcb abcbb.
You are given an integer and "conditions" (). Let's say that string , consisting of lowercase Latin letters, is good if all conditions are satisfied at the same time. A condition is a pair and have the following meaning:
- , i. e. a prefix of of length contains exactly unique palindromic substrings.
Find a good string or report that such doesn't exist.
Look in Notes if you need further clarifications.
Input
Each test contains multiple test cases. The first line contains the number of test cases (). The description of the test cases follows.
The first line of each test case contains two integers and (; ) — length of good string and number of conditions.
The second line of each test case contains integers () where is the length of the prefix in the -th condition.
The third line of each test case contains integers () where is the number of palindromic substrings in the -th condition.
It is guaranteed that the sum of over all test cases does not exceed .
Output
For each test case, if there is no good string of length that satisfies all conditions, print NO.
Otherwise, print YES and a string of length , consisting of lowercase Latin letters, that satisfies all conditions. If there are multiple answers, print any of them.
Example
input
7 10 2 5 10 5 6 3 1 3 3 4 2 3 4 3 3 4 2 3 4 3 4 4 1 4 5 10 3 4 6 10 4 5 8 10 4 4 6 7 10 4 5 7 8
output
YES
abcbbcabcb
YES
foo
YES
ayda
YES
wada
NO
YES
abcbcacbab
NO
Note
In the first test case, string abcbbcabcb satisfies conditions:
- abcbb. Palindromic substrings are a, b, c, bb and bcb.
- abcbbcabcb. Palindromic substrings are the same as above, and one extra substring cbbc.
In the second test case, string foo satisfies condition:
- foo. Palindromic substrings are f, o and oo.
There are other possible answers.
In the third test case, string ayda satisfies conditions:
- ayd. Palindromic substrings are a, y and d.
- ayda. Palindromic substrings are the same.
In the fourth test case, string wada satisfies conditions:
- wad. Palindromic substrings are w, a and d.
- wada. Palindromic substrings are the same, and one extra substring ada.
In the fifth test case, it can be proven that there is no string of length which has palindromic substrings.
In the sixth test case, string abcbcacbab satisfies conditions:
- abcb. Palindromic substrings are a, b, c and bcb.
- abcbca. Palindromic substrings are the same, and one extra substring cbc.
- abcbcacbab. Palindromic substrings are the same, and three extra substrings cac, bab and bcacb.
解题思路
先手动模拟较小的情况,看看唯一回文子串个数是多少。
如果,那么。
如果,只有两种情况 aa 和 ab ,都有。
如果,有种情况,即分别考虑第个与第个字符是否与前一个相同,那么就有种。即 aaa,aab,aba,abc,都有。这也是为什么数据中的和都至少为。
如果,那么前个字符对已经有个贡献,如果往字符串最后添加一个字符,那么新的字符串的只能比之前的增加或。反证法,假设,那么选择出两个新的回文子串,这两个新的回文子串的结尾字符必然是,并且这两个回文子串的长度必然不一样。不妨设长度大的子串的左端点为,长度小的子串的左端点为,那么有,两个回文子串的右端点均为(即字符的位置)。根据回文的定义,必然是的前缀与后缀,可以参考下图:
回文子串与是同一个,而我们已经把前面的统计到了。所以如果存在以结尾的回文子串那么应该只统计长度最长的那一个,因为任何短的回文子串在之前已经统计过了。故多加一个字符最多会使得增加。
我们先构造出一些特别的子串,时有 aaaaaa... ;时有 abcabc... 。
然后我们先考虑的情况,即只有一个约束条件。首先根据上面的结论知道如果,那么无解。否则先构造出个 a(注意),然后用 abc 填补直到字符串的长度为。那么就会得到这种形式:aaa...aaabcabc... 。
考虑。首先如果,那么无解,因为添加个字符最多使得增加。否则我们任取一个之前没用过的字符(由于最多只有个约束,因此个小写字母足够用),然后往答案后面添加个,然后再用 abc 去填充直到字符的长度变成。那么得到的字符串就会是这种形式,其中表示 | 各个约束的边界: aaaaaaaaabcabcab|dddddcabcabca|eeebcab 。
注意到每次填充 abc 都是从上一次结束字符的下一个开始,比如上一次约束最后填充到 a ,那么下一次应该从 b 开始继续填充,这样做可以避免产生不必要的回文。否则比如 ...ddabca|eabc... ,那么就会形成回文 aea 。
AC代码如下:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 2e5 + 10; 5 6 int x[N], c[N]; 7 8 void solve() { 9 int n, m; 10 scanf("%d %d", &n, &m); 11 for (int i = 0; i < m; i++) { 12 scanf("%d", x + i); 13 } 14 for (int i = 0; i < m; i++) { 15 scanf("%d", c + i); 16 } 17 if (c[0] > x[0]) { // P<=n 18 printf("NO\n"); 19 return; 20 } 21 string ans; 22 int t = 0; 23 // 处理第一个约束 24 for (int i = 0; i < c[0] - 3; i++) { 25 ans += 'a'; 26 } 27 for (int i = c[0] - 3; i < x[0]; i++) { 28 ans += 'a' + t; 29 t = (t + 1) % 3; 30 } 31 //处理剩下的约束 32 for (int i = 1; i < m; i++) { 33 if (c[i] - c[i - 1] > x[i] - x[i - 1]) { 34 printf("NO\n"); 35 return; 36 } 37 for (int j = c[i - 1]; j < c[i]; j++) { // 添加c[i]-c[i-1]个之前没出现过的字符 38 ans += 'c' + i; 39 } 40 while (ans.size() < x[i]) { // 用abc填补到长度x[i] 41 ans += 'a' + t; 42 t = (t + 1) % 3; 43 } 44 } 45 while (ans.size() < n) { // 记得最后把字符串填补到长度n 46 ans += 'a' + t; 47 t = (t + 1) % 3; 48 } 49 printf("YES\n%s\n", ans.c_str()); 50 } 51 52 int main() { 53 int t; 54 scanf("%d", &t); 55 while (t--) { 56 solve(); 57 } 58 59 return 0; 60 }
参考资料
Codeforces Round #868 (Div.2) Editorial:https://codeforces.com/blog/entry/115465
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/17362911.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效