CF135E Weak Subsequence(弱子串)

Weak Subsequence

题目描述

Little Petya very much likes strings. Recently he has received a voucher to purchase a string as a gift from his mother. The string can be bought in the local shop. One can consider that the shop has all sorts of strings over the alphabet of fixed size. The size of the alphabet is equal to kkk. However, the voucher has a string type limitation: specifically, the voucher can be used to purchase string sss if the length of string’s longest substring that is also its weak subsequence (see the definition given below) equals www.

String aaa with the length of nnn is considered the weak subsequence of the string sss with the length of mmm, if there exists such a set of indexes 1≤i1≤i2≤⋯≤in≤m1\le i_{1}\le i_{2}\le \cdots \le i_{n}\le m1i1i2inm , that has the following two properties:

ak=sika_k = s_{ik}ak=sik for all k from 111 to nnn
there exists at least one such k(1≤k≤n)k (1 \le k \le n )k(1kn), for which ik+1–ik<1i_{k+1}–i_{k} < 1ik+1ik<1
.
Petya got interested how many different strings are available for him to purchase in the shop.

解题:

一、先简单翻译一下

  • 原始的字符串sss:长为nnn,由kkk个字母表里的字母组成;
  • 子串aaa:长为mmm,是sss的子串;
  • 若 子串aaa与字符串sss中的一个子序列相等,且aaaiii至少有一个元素不同,则称子串aaa为弱子串。
  • 题目目标是统计 最长的弱子串aaa 的长度 mmm 等于给定的值 www 的 原始字符串sss 的个数

二、找到弱子串存在的充要条件

弱子串aaa 的定义与字符串sss中的一个子序列有关,这是“存在”的关系。
我们定义字符串sss中子串aaa左侧为前缀为iii、右侧为后缀为jjj。我们发现,那么如果前缀iii中包含子串aaa的首字母,或者后缀jjj中包含子串aaa的尾字母,那么aaa一定为弱子串。

三、界定弱子串是是否最长,即,找到最长弱子串

我们对弱子串的判断,是借助前缀和后缀中是否包含子串的首尾字母来实现的,但这是定性的分析。我们对其做定量的分析。

首先,从条件上来看,只要前缀或后缀中,有一个首字母或尾字母就可以满足要求。
如果,存在两个以上的字母,我们可以将前缀中,第二个出现的字母往右并入子串,或者将后缀中,第一个出现的字母往左并入子串。此时该子串仍为弱子串,且长度增加。
这验证了两件事:

  1. 前缀或后缀中存在两个以上的首字母或尾字母,则当前子串并非最长;
  2. 最长的子串前缀或后缀中有且只有一个首字母或尾字母。

第二条是我们寻找最长弱子串的条件。

四、求最长弱子串的长度,然后计算所有可能性

长弱子串的长度 mmm = n−min(i,j)n - min(i, j)nmin(i,j), 其中i为前缀长,j为后缀长。
在满足条件的所有可能中,mmm的值为www,而nnniiijjj的值受到
kkk的限制。分情况讨论前缀、后缀与中间子串的关系,即可求的答案

### 关于 `__weak` 的概念及其在 C++ 和 Python 中的应用 #### 什么是符号 (`__weak`)? 在编译器层面,符号可以分为强符号和符号。符号允许程序中存在多个同名的定义,而链接器会选择其中一个作为最终使用的版本。这种机制通常用于实现可选功能或者提供默认行为。 在嵌入式开发领域(如 U-Boot 和 Linux Kernel),`__weak` 是一种常用的修饰符,用来标记函数或变量为符号[^2]。这意味着如果其他地方提供了相同名称的强符号,则该强符号会被优先使用;如果没有,则回退到符号。 --- #### 在 C++ 中如何定义和使用函数? 以下是基于 GCC 编译器的一个简单例子: ```cpp // weak_function.cpp #include <iostream> // 声明一个函数 extern "C" __attribute__((weak)) void my_weak_function() { std::cout << "Default implementation of weak function." << std::endl; } void call_my_function() { if (my_weak_function) { // 检查是否存在强符号覆盖 my_weak_function(); } else { std::cout << "No strong symbol found, skipping..." << std::endl; } } ``` 在这个例子中: - 如果外部模块重新实现了 `my_weak_function()` 并将其声明为强符号,则此版本将被调用。 - 若没有任何重写发生,默认的实现就会生效。 需要注意的是,在标准 C++ 中并没有直接支持类似的特性,因此它依赖特定平台扩展(比如 GNU 的 `__attribute__((weak))` 或 MSVC 下的不同方法)。上述代码适用于 GCC/Clang 环境下运行。 --- #### 对于 Python 来说是否有类似的概念呢? 严格意义上讲,Python 不具备像 C/C++ 那样的静态绑定阶段以及相应的“符号”概念。然而,我们可以通过动态导入或其他设计模式模拟某种形式的行为: 假设有一个插件系统希望让用户能够替换某些默认处理逻辑而不强制修改核心库文件本身的话,可以采用如下方式之一——利用 try-except 结构尝试加载用户自定义模块并设置回调路径: ```python try: from user_defined import custom_handler as handler except ImportError: def handler(): print("Using default handler.") handler() ``` 这里展示了即使不存在名为 'user_defined' 的包时也不会中断执行流程而是转而应用内置方案的情况。这类似于 C 当中的引用效果。 另外值得注意的一点是在多线程环境下操作 python 解析器对象(Python Interpreter State),由于全局解释锁(Global Interpreter Lock,GIL)的存在使得同一时刻只有一个原生线程能够在CPython VM内部真正获得控制权去评估字节码指令序列。所以在混合编程场景里务必记得适时管理gil状态以避免潜在死锁风险[^3]. --- ### 总结 虽然两者之间存在着本质区别(C 属底层硬件抽象层面上的操作 而 Py 则偏向高层级脚本语言范畴),但是它们都试图解决同一个问题即灵活性与兼容性的平衡取舍.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值