【贪心/Trie】【CF1083B】 The Fair Nut and Strings
Description
有 个长度为 的只含 或 字符串,并不知道它们具体是多少,只知道它们的字典序不小于字符串 ,同时不大于字符串 。定义一个字符串是合法的当且仅当它是这 个字符串之一的前缀(如果它是多个串的前缀那么只计算一次)。求合法的字符串最大可能是多少
Input
第一行是两个整数 和
下面两行,第一行是长度为 的字符串 ,第二行是长度为 的字符串
Output
输出一个数代表答案。
Hint
Solution
我们考虑假如对这 个字符串建出一棵踹Trie树,那么显然一个节点对应一个合法的字符串,答案即为树上节点个数。于是我们的问题即被转化为了最大化Trie树上的节点个数。考虑在一个节点,在合法的条件下孩子数为 的答案显然不劣于孩子数为 的答案。于是我们依照此按照层数进行贪心,尽可能的多分节点即可。考虑因为最后一层的节点最多有 个,所以当算到一层的节点数不小于 时,后面就无需枚举,直接分配给每层 个节点计算答案即可。
Code
#include <cstdio>
#include <algorithm>
#ifdef ONLINE_JUDGE
#define freopen(a, b, c)
#endif
#define rg register
#define ci const int
#define cl const long long
typedef long long int ll;
namespace IPT {
const int L = 1000000;
char buf[L], *front=buf, *end=buf;
char GetChar() {
if (front == end) {
end = buf + fread(front = buf, 1, L, stdin);
if (front == end) return -1;
}
return *(front++);
}
}
template <typename T>
inline void qr(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
if (lst == '-') x = -x;
}
template <typename T>
inline void ReadDb(T &x) {
rg char ch = IPT::GetChar(), lst = ' ';
while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
if (ch == '.') {
ch = IPT::GetChar();
double base = 1;
while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
}
if (lst == '-') x = -x;
}
namespace OPT {
char buf[120];
}
template <typename T>
inline void qw(T x, const char aft, const bool pt) {
if (x < 0) {x = -x, putchar('-');}
rg int top=0;
do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
while (top) putchar(OPT::buf[top--]);
if (pt) putchar(aft);
}
const int maxn = 500010;
ll n, k, ans;
char MU[maxn], CU[maxn];
int main() {
freopen("1.in", "r", stdin);
qr(n); qr(k);
do MU[1] = IPT::GetChar(); while ((MU[1] > 'z') || (MU[1] < 'a'));
for (rg int i = 2; i <= n; ++i) MU[i] = IPT::GetChar();
do CU[1] = IPT::GetChar(); while ((CU[1] > 'z') || (CU[1] < 'a'));
for (rg int i = 2; i <= n; ++i) CU[i] = IPT::GetChar();
ll pre = 1;
for (rg int i = 1; i <= n; ++i) {
pre <<= 1;
if (MU[i] == 'b') --pre;
if (CU[i] == 'a') --pre;
if (pre >= k) {
ans += 1ll * k * (n - i + 1);
break;
}
ans += pre;
}
qw(ans, '\n', true);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具