An impassioned circulation of affection ( Codeforces Round 418 (Div. 2) )

An impassioned circulation of affection ( Codeforces Round 418 (Div. 2) )

Nadeko’s birthday is approaching! As she decorated the room for the party, a long garland of Dianthus-shaped paper pieces was placed on a prominent part of the wall. Brother Koyomi will like it!

Still unsatisfied with the garland, Nadeko decided to polish it again. The garland has n pieces numbered from 1 to n from left to right, and the i-th piece has a colour s i s_i si, denoted by a lowercase English letter. Nadeko will repaint at most m of the pieces to give each of them an arbitrary new colour (still denoted by a lowercase English letter). After this work, she finds out all subsegments of the garland containing pieces of only colour c — Brother Koyomi’s favourite one, and takes the length of the longest among them to be the Koyomity of the garland.

For instance, let’s say the garland is represented by “kooomo”, and Brother Koyomi’s favourite colour is “o”. Among all subsegments containing pieces of “o” only, “ooo” is the longest, with a length of 3. Thus the Koyomity of this garland equals 3.

But problem arises as Nadeko is unsure about Brother Koyomi’s favourite colour, and has swaying ideas on the amount of work to do. She has q plans on this, each of which can be expressed as a pair of an integer $m_i a n d a l o w e r c a s e l e t t e r ∗ and a lowercase letter * andalowercaseletterc_i$*, meanings of which are explained above. You are to find out the maximum Koyomity achievable after repainting the garland according to each plan.

Input

The first line of input contains a positive integer n (1 ≤ n ≤ 1 500) — the length of the garland.

The second line contains n lowercase English letters s1s2… s n s_n sn as a string — the initial colours of paper pieces on the garland.

The third line contains a positive integer q (1 ≤ q ≤ 200 000) — the number of plans Nadeko has.

The next q lines describe one plan each: the i-th among them contains an integer m i m_i mi (1 ≤  m i m_i mi ≤ n) — the maximum amount of pieces to repaint, followed by a space, then by a lowercase English letter c i c_i ci — Koyomi’s possible favourite colour.

Output

Output q lines: for each work plan, output one line containing an integer — the largest Koyomity achievable after repainting the garland according to it.

Examples

Input

6koyomi31 o4 o4 m

Output

365

Input

15yamatonadeshiko101 a2 a3 a4 a5 a1 b2 b3 b4 b5 b

Output

3457812345

Input

10aaaaaaaaaa210 b10 z

Output

1010
Note

In the first sample, there are three plans:

  • In the first plan, at most 1 piece can be repainted. Repainting the “y” piece to become “o” results in “kooomi”, whose Koyomity of 3 is the best achievable;
  • In the second plan, at most 4 pieces can be repainted, and “oooooo” results in a Koyomity of 6;
  • In the third plan, at most 4 pieces can be repainted, and “mmmmmi” and “kmmmmm” both result in a Koyomity of 5.

这道题的核心思想是通过预处理来减少查询时的计算量,从而提高效率。我们可以通过枚举所有可能的区间(O(n^2))以及所有可能的目标颜色(26个字母),计算每个区间内需要多少修改才能将所有字符变为目标颜色,并将这些结果保存下来。这样在查询时,时间复杂度就降到了常数级别。

问题分析

  1. 查询次数与预处理的关系

    • 给定花环的长度 n,最大可能的答案数量是 1500 * 26 = 39000,远小于 q = 200000,所以这意味着我们需要进行有效的预处理,避免在每个查询时进行复杂的计算。
  2. 预处理思路

    • 对于每一个目标颜色 c(26个字母),我们需要计算所有子区间 [i, j] 需要多少修改才能使得该区间内的所有字符都变成颜色 c
    • 可以通过 前缀和 来加速计算某个子区间内的字符出现次数,从而得到需要修改的字符数。
  3. 优化

    • 通过前缀和数组,可以在 O(1) 时间内计算任意区间内某个字符的出现次数。这样我们就能在 O(n^2) 的时间复杂度内处理所有区间,之后再通过枚举颜色来进一步降低复杂度。
    • 预处理的时间复杂度是 O(n^2 * 26),这对于 n ≤ 1500 是可以接受的。
  4. 最终的查询处理

    • 在查询时,如果某个答案已经预处理过了,就直接返回预计算的值。如果没有预处理过,就利用剩余的修改次数,将剩余字符改为目标颜色,然后直接返回 n(即最大连续长度是整个字符串)。

代码实现

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define endl '\n'
#define int long long
#define Max(a, b) (((a) > (b)) ? (a) : (b))
#define Min(a, b) (((a) < (b)) ? (a) : (b))
#define BoBoowen ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
using namespace std;

const int inf = 1e9 + 7;
const int N = 1500 + 10;

int n;
string s;
int q;
int qz[30][N];
int dp[30][N];
map<char, int> mp;

int ask(int can, char c)
{
    int x = c - 'a';
    for (int i = 1; i <= n; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (i > j)
            {
                continue;
            }
            dp[x][j - i + 1 - (qz[x][j] - qz[x][i - 1])] = max((dp[x][j - i + 1 - (qz[x][j] - qz[x][i - 1])]), (j - i + 1));
        }
    }
    for (int i = 1; i <= n; ++i)
    {
        dp[x][i] = max(dp[x][i], dp[x][i - 1] + 1);
    }
    mp[c] = 1;
    return min(dp[x][can], n);
}

void solved()
{
    cin >> n >> s >> q;

    s = ' ' + s;
    for (int i = 0; i < 26; ++i)
    {
        for (int j = 1; j <= n; ++j)
        {
            if (s[j] - 'a' != i)
            {
                qz[i][j] = qz[i][j - 1];
            }
            else
            {
                qz[i][j] = qz[i][j - 1] + 1;
            }
        }
    }

    while (q--)
    {
        int can;
        char c;
        cin >> can >> c;
        if (mp[c] == 0)
        {
            cout << ask(can, c) << endl;
        }
        else
        {
            cout << min(dp[c - 'a'][can], n) << endl;
        }
    }
}

signed main()
{
    BoBoowen;

    int T = 1;
    // cin >> T;
    while (T--)
    {
        solved();
    }
}

代码分析

  1. qz数组的计算

    • 对于每一个目标颜色(26个字母),我们用一个前缀和数组 qz[c][i] 表示从第1个字符到第i个字符中,目标颜色字符的个数。
    • qz[c][i] 表示在字符串 s 中,前 i 个字符中有多少个目标颜色 c
  2. precompute函数

    • 通过双重循环枚举区间 [i, j],然后使用前缀和来计算区间内需要修改的字符数量。
    • 对于每个目标颜色 c,我们计算当前区间需要修改的字符数量,并更新 ans[i][j],即使区间 [i, j] 修改成目标颜色需要的最小修改次数。
  3. 查询处理

    • 对于每个查询,我们只需检查修改次数是否符合要求,若符合,更新最大连续子段的长度。

复杂度分析

  1. 预处理阶段

    • 对于每个目标颜色 c(共26个),我们计算前缀和的时间复杂度是 O(n).
    • 然后,枚举所有区间 [i, j],每次计算一个区间所需要的修改次数,时间复杂度是 O(n^2).
    • 因此,预处理的总体时间复杂度为 O(n^2 * 26),即 O(n^2)
  2. 查询阶段

    • 每个查询的时间复杂度为 O(1),因为查询操作仅仅是通过已预处理的结果来得到答案。

结论

通过前缀和的优化,我们将原本的暴力枚举区间的时间复杂度降低到了 O(n^2 * 26),这是可以接受的,因此这个方法能够有效地处理大规模的输入数据,满足题目的时间要求。

你可能感兴趣的:(acm训练集合,暴力枚举,dp,双指针)