CF 917.B. Erase First or Second Letter(1100)

题目

思路:

1、一开始的想的是用map记录下每一个出现过的字符串,但是最后空间会不够,所以放弃

2、我们可以发现在经过删除后得到的字符串(长度为 m,原本字符串长度为 n )中,后n - m - 1位的字符永远相同,所以求不同的字符串数量就是求这些后面字符串的前面,有多少种不同的字母,然后删减次数从 1,慢慢增加到 n - 1,累加起来的结果就是答案了

eg:abcdeeeefg(n = 10),在经过 4 次删除后,后m(10 - 4 - 1)= 5位字符串("eeefg")永远相同

#include <iostream>
#include <algorithm>
#include <cstring>
#include <map>

using namespace std;

int T;

void solve()
{
    int n;
    string s;

    cin >> n >> s;

    map<char, int> p;
    long long ans = 0, cnt = 0;
    
    for (int i = 0; i < n; i ++ )
    {
        char t = s[i];
        if (p[t] == 0)
        {
            p[t] ++ ;
            cnt ++ ;
        }

        ans += cnt;
    }

    cout << ans << endl;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);

    cin >> T;
    while (T -- )
    {
        solve();
    }
    return 0;
}

借鉴了一下大佬的题解

在嵌入式系统中,`nand erase.chip` 和 `mtd erase nand0` 是两种不同的 NAND Flash 擦除方式,分别属于 **U-Boot 命令层** 和 **Linux MTD 子系统** 的操作方式。它们的“清除干净程度”取决于实现方式和底层驱动。 --- ## ✅ 一、命令说明与对比: | 命令 | 来源 | 说明 | |------|------|------| | `nand erase.chip` | U-Boot 命令 | 对整个 NAND Flash 芯片进行擦除 | | `mtd erase /dev/mtd0` 或 `flash_erase` | Linux MTD 子系统 | 通过 MTD 驱动擦除某个 MTD 分区 | --- ## ✅ 二、谁“清得更干净”? ### 1. **`nand erase.chip`(U-Boot)** - **功能**:调用 NAND 控制器直接擦除整个 NAND Flash 芯片。 - **实现方式**: - 直接访问 NAND 控制器寄存器。 - 擦除每个 block,跳过坏块。 - **优点**: - 更底层,绕过 MTD 子系统,更彻底。 - 不依赖分区表,擦除整个芯片。 - **缺点**: - 只能在 U-Boot 环境中使用。 - 无法指定擦除某个分区。 ### 2. **`mtd erase /dev/mtd0`(Linux)** - **功能**:通过 MTD 接口擦除某个 MTD 分区(如 mtd0)。 - **实现方式**: - 调用 MTD 驱动的 `erase` 函数。 - 会跳过坏块。 - **优点**: - 在 Linux 系统中使用方便。 - 可以精确控制擦除的 MTD 分区。 - **缺点**: - 只擦除指定的 MTD 分区,不是整个芯片。 - 依赖 MTD 分区表和驱动实现。 --- ## ✅ 三、谁更“干净”? | 比较项 | `nand erase.chip` | `mtd erase` | |--------|------------------|-------------| | 是否擦除整个 NAND | ✅ 是 | ❌ 否(仅擦除指定分区) | | 是否跳过坏块 | ✅ 是 | ✅ 是 | | 是否影响所有分区 | ✅ 是 | ❌ 否 | | 是否底层操作 | ✅ 是 | ❌ 否(依赖 MTD 子系统) | | 是否适用于 Linux | ❌ 否 | ✅ 是 | ### ✅ 结论: > **`nand erase.chip` 更“干净”**,因为它擦除的是整个 NAND Flash 芯片的所有可用块(跳过坏块),不依赖分区表;而 `mtd erase` 只擦除某个 MTD 分区,范围有限。 --- ## ✅ 四、示例代码(U-Boot 中的 NAND 擦除流程) ```c // U-Boot 中 nand erase.chip 的核心逻辑(伪代码) int do_nand_chip_erase(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { struct mtd_info *mtd = get_nand_mtd_device(); // 获取 NAND 设备 struct erase_info ei; uint64_t chip_size = mtd->size; ei.addr = 0; ei.len = chip_size; ei.callback = NULL; while (ei.addr < chip_size) { if (!nand_block_isbad(mtd, ei.addr)) { mtd->erase(mtd, &ei); // 调用 NAND 驱动的擦除函数 } ei.addr += mtd->erasesize; } return 0; } ``` --- ## ✅ 五、使用建议 | 使用场景 | 推荐命令 | |----------|----------| | 想彻底清除整个 NAND Flash | `nand erase.chip` | | 仅擦除某个分区(如 uboot 分区) | `mtd erase /dev/mtd0` | | 在 Linux 中操作 NAND | 使用 `flash_erase` 工具或 `mtd-utils` | | 在 U-Boot 中操作 NAND | 使用 `nand erase` 或 `nand erase.chip` | --- ##
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值