Codeforces Round (Div.3) C.Sort (前缀和的应用)

原题:

time limit per test:5 seconds

memory limit per test:256 megabytes

You are given two strings a and b of length n. Then, you are (forced against your will) to answer q queries.

For each query, you are given a range bounded by l and r. In one operation, you can choose an integer i (l≤i≤r) and set ai=x where x is any character you desire. Output the minimum number of operations you must perform such that sorted(a[l..r])=sorted(b[l..r]). The operations you perform on one query does not affect other queries.

For an arbitrary string c, sorted(c[l..r]) denotes the substring consisting of characters cl,cl+1,...,cr sorted in lexicographical order.

Input

The first line contains t (1≤t≤1000) – the number of test cases.

The first line of each test case contains two integers nn and q (1≤n,q≤2⋅10^5) – the length of both strings and the number of queries.

The following line contains a of length n. It is guaranteed aa only contains lowercase latin letters.

The following line contains b of length n. It is guaranteed bb only contains lowercase latin letters.

The following q lines contain two integers l and r (1≤l≤r≤n) – the range of the query.

It is guaranteed the sum of n and q over all test cases does not exceed 2⋅10^5.

Output

For each query, output an integer, the minimum number of operations you need to perform in a new line.

翻译:

问题描述:

你被给定了两个长度为 n 的字符串 ab。然后,你需要(虽然是被迫的)回答 q 个查询。

对于每个查询,你会得到一个由 lr 确定的范围。在一个操作中,你可以选择一个整数 il ≤ i ≤ r)并将 a[i] 设置为你希望的任何字符。输出你必须执行的最小操作次数,以确保 sorted(a[l..r]) = sorted(b[l..r])。你对一个查询执行的操作不会影响其他查询。

对于任意字符串 csorted(c[l..r]) 表示在 c[l]c[r] 的子字符串中按字典序排序后的子字符串。

输入:

第一行包含 t1 ≤ t ≤ 1000)—— 测试用例的数量。

每个测试用例的第一行包含两个整数 nq1 ≤ n, q ≤ 2⋅10^5)—— 两个字符串的长度和查询的数量。

接下来一行包含长度为 n 的字符串 a。字符串 a 只包含小写字母。

接下来一行包含长度为 n 的字符串 b。字符串 b 只包含小写字母。

接下来 q 行,每行包含两个整数 lr1 ≤ l ≤ r ≤ n)—— 查询的范围。

保证所有测试用例中 nq 的总和不超过 2⋅10^5

输出:

对于每个查询,输出一个整数,表示你需要执行的最小操作次数,每个查询输出一行。

Cf的题属于是想到就出结果,想不到就卡死,没有很多的模板可以套用,必须要先观察,千万不要上来就暴力,很可能连签到都过不去哦

观察发现,这道题其实就是求在一个区间当中,两个字符串有多少个字符不同的数量,那可以假设一下,如果暴力来敲,先截取[l,r]的字符串,然后排序,然后去遍历一遍看有多少不同

如果是这样想基本就陷入到坑里面出不来了,因为的话按照字典序排序之后,你没办法要求两个字符串中相同的字符的字符位置一一对应,不同的一一对应,是有这种情况的,那么在看题目本身的需求,就是求有多少不同的个数,那其实对每个字符串求前缀和,记录第i个位置的26字母分别出现的次数,然后在给出区间之后在去对比前缀和中26字母数量的差异,相同就不用管,不同就加上不同的个数,最后除以2(因为两个字符串都加了一遍)

代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>

using namespace std;

void solve() {
    int n, q;
    cin >> n >> q;
    vector<vector<int>> pre1(n + 1,vector<int>(26,0));
    vector<vector<int>> pre2(n + 1,vector<int>(26,0));
    for(int i = 1;i <= n;i ++){
        char ch;
        cin >> ch;
        pre1[i][ch - 'a'] ++;
        for(int j = 0;j < 26;j ++){
            pre1[i][j] += pre1[i - 1][j];
        }
    }
    for(int i = 1;i <= n;i ++){
        char ch;
        cin >> ch;
        pre2[i][ch - 'a'] ++;
        for(int j = 0;j < 26;j ++){
            pre2[i][j] += pre2[i - 1][j];
        }
    }  

    while(q --){
        int l,r;
        int res = 0;
        cin >> l >> r;
        for(int i = 0;i < 26;i ++){
            int A = pre1[r][i] - pre1[l - 1][i];
            int B = pre2[r][i] - pre2[l - 1][i];
            res += abs(A - B);
        }
        cout << res / 2 << endl; 
    }
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

加油

  • 13
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Codeforces Round 894 (Div. 3) 是一个Codeforces举办的比赛,是第894轮的Div. 3级别比赛。它包含了一系列题目,其中包括题目E. Kolya and Movie Theatre。 根据题目描述,E. Kolya and Movie Theatre问题要求我们给定两个字符串,通过三种操作来让字符串a等于字符串b。这三种操作分别为:交换a中相同位置的字符、交换a中对称位置的字符、交换b中对称位置的字符。我们需要先进行一次预处理,替换a中的字符,然后进行上述三种操作,最终得到a等于b的结果。我们需要计算预处理操作的次数。 根据引用的讨论,当且仅当b[i]==b[n-i-1]时,如果a[i]!=a[n-i-1],需要进行一次操作;否则不需要操作。所以我们可以遍历字符串b的前半部分,判断对应位置的字符是否与后半部分对称,并统计需要进行操作的次数。 以上就是Codeforces Round 894 (Div. 3)的简要说明和题目E. Kolya and Movie Theatre的要求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Codeforces Round #498 (Div. 3) (A+B+C+D+E+F)](https://blog.csdn.net/qq_46030630/article/details/108804114)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *3* [Codeforces Round 894 (Div. 3)A~E题解](https://blog.csdn.net/gyeolhada/article/details/132491891)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值