Gym - 101972H Beautiful Substrings(暴力)

题目链接:

http://codeforces.com/gym/101972/problem/H

题目:

You are given two strings a and b consisting of lowercase English letters. A beautiful substring is defined as a substring of any length of string b such that the first and last letters of it are the same as the first and last letters of any substring of length k of string a.

Your task is to count the number of beautiful substrings. Can you?

Input

The first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.

The first line of each test case contains three integers nm, and k (1 ≤ n, m ≤ 105, 1 ≤ k ≤ n), in which n is the length of string am is the length of string b, and kis the described variable in the statement.

Then two lines follow, the first line contains a string a of length n and the second line contains a string b of length m. Both strings consist only of lowercase English letters.

Output

For each test case, print a single line containing the number of beautiful substrings

Example

Input

2
4 5 3
acbd
abcbd
3 3 1
kkd
dkd

Output

3
4

Note

A substring of a string s is a sequence slsl + 1, ..., sr for some integers (l, r)such that (1 ≤ l ≤ r ≤ n), in which n is the length of the string s.

题目大意:

有一个长度为n的字符串a,和一个长度为m的字符串b,然后给你一个k。对于任何一个b的子串,如果能在a中找到一个长度为k的子串,开头结尾分别与b的那个子串相同,那么,这个b的子串就是一个美丽的子串,现在问你b一共有多少个美丽的子串。

题目分析:

因为a中长度为k的字符串的开头结尾一共最多也就是26 * 26种可能(开头26个字母选一个,结尾26个字母选一个)。然后对每一种可能我们都可以在O(n)的时间得到答案,那么,我们就可以预处理出来a中所有的长度为k的子串的开头和结尾(去重),然后暴力就行了。

然后有个坑,就是答案要用long long 来记录。

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <set>

using namespace std;
const int MAXN = 100000 + 100;
char a[MAXN], b[MAXN];

int main() {
    int T;
    scanf("%d", &T);
    while (T--) {
        int n, m, k;
        long long num = 0;
        set<pair<char, char> > s;
        scanf("%d %d %d", &n, &m, &k);
        scanf(" %s %s", a, b);
        for (int i = 0; i + k - 1 < n; i++)
            s.insert(make_pair(a[i], a[i + k - 1]));
        for (auto i : s) {
            char s = i.first, e = i.second;
            long long nume = 0;
            if (s != e) {
                for (int j = m - 1; j >= 0; j--) {
                    if (b[j] == e) {
                        nume++;
                    } else if (b[j] == s) {
                        num += nume;
                    }
                }
            } else {
                for (int j = m - 1; j >= 0; j--) {
                    if (b[j] == e) {
                        nume++;
                        num += (nume);
                    }
                }
            }
        }
        printf("%lld\n", num);
    }
    return 0;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值